C#继承:重写后仍然调用我的虚拟函数

问题描述 投票:0回答:1

在我的游戏中,有武器管理器(交换武器),武器脚本(具有射击方法的武器的基类)和武器。

我将射击代码从武器管理员转移到了武器本身。但是现在我已经覆盖了Fire方法,没有调用base方法,但是它仍然调用了virtual方法。我正在尝试使用新行为来覆盖更新,但它确实会通过该代码。

类定义:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(AudioSource))]     //Require an AudioSource
public class Weapon : MonoBehaviour
{
    protected bool canFire = true;  
    protected AudioSource audioSrc;
    protected float timer;
    [SerializeField]protected List<AudioClip> soundClips = new List<AudioClip>();
    [SerializeField]protected Transform firePoint;
    [SerializeField]protected GameObject projectile;
    [SerializeField]protected ParticleSystem particles;
    [SerializeField]protected float fireRate = 1f;       
    [SerializeField]protected int ammoCount = 5;
    [SerializeField]protected float projVel = 5f;

    void Start()
    {
        audioSrc = GetComponent<AudioSource>();
        audioSrc.playOnAwake = false;  
    }

    virtual public void Update()
    {
        if (!canFire)  
            timer += Time.deltaTime;
            if (timer >= fireRate) 
                canFire = true;

        if (Input.GetButtonDown("Fire1"))  
            Fire();

    }

    virtual public void Fire()
    {
        Debug.Log("Called Default Fire");
        if (canFire)        
        {
            Instantiate(projectile, firePoint.transform.position, firePoint.transform.rotation);
            PlaySound();
            PlayParticles();
            canFire = false;
            timer = 0;
        }
    }

    virtual public void PlaySound()     
    {
        if (soundClips.Count < 0)
        {
            audioSrc.clip = soundClips[Random.Range(0, soundClips.Count)];  
            audioSrc.Play();
        }
    }

    virtual public void PlayParticles()     
    {
        if (particles != null)
            particles.Play();

    }

}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class C4 : Weapon
{
    [SerializeField] float radius = 5f;
    List<GameObject> c4Placed = new List<GameObject>();

    void Start()
    {

    }

    public override void Update()
    {
        //base.Update();

        if (Input.GetKeyDown(KeyCode.Mouse0)) { //Fire Weapon (Left-click)
            this.Fire();
        }

        if (Input.GetKeyDown(KeyCode.Mouse1))    //Right Click
        {
            Place();
        }       //Left click is placing but no fire??????
    }       

    public override void Fire()
    {
        if (canFire)        //TODO: account for ammo        //canfire not based on timer but c4 placed < 0 (set interval to 0/low)
        {
            canFire = false;
            timer = 0;
            ExplodeAll();
        }
        Debug.Log("Called Override Fire");
    }

    public void Place()
    {
        Debug.Log("Called Place");
        //if (canFire)
        c4Placed.Add(Instantiate(projectile, firePoint.transform.position, firePoint.transform.rotation));    //Instantiate the c4 
        //on c4 have it move forward a tiny bit and attach to first surface it reaches
    }

    //Keep list of placed c4
    void ExplodeAll()
    {
        foreach(GameObject g in c4Placed)
        {
            g.GetComponent<C4Block>().Explode();     //Get c4 in place instead of the gameobject and use c4 list instead? (still reference gameobject when exploding)
            //play sound and particles for each c4
            //TODO: add explosive force
        }
    }

}
c# unity3d game-engine
1个回答
0
投票

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(AudioSource))]     //Require an AudioSource
public class Weapon : MonoBehaviour
{
    protected bool canFire = true;  
    protected AudioSource audioSrc;
    protected float timer;
    [SerializeField]protected List<AudioClip> soundClips = new List<AudioClip>();
    [SerializeField]protected Transform firePoint;
    [SerializeField]protected GameObject projectile;
    [SerializeField]protected ParticleSystem particles;
    [SerializeField]protected float fireRate = 1f;       
    [SerializeField]protected int ammoCount = 5;
    [SerializeField]protected float projVel = 5f;

    void Start()
    {
        audioSrc = GetComponent<AudioSource>();
        audioSrc.playOnAwake = false;  
    }

    virtual public void Update()
    {
        if (!canFire)  
            timer += Time.deltaTime;
            if (timer >= fireRate) 
                canFire = true;

        if (Input.GetButtonDown("Fire1"))  
            Fire();

    }

    virtual public void Fire()
    {
        Debug.Log("Called Default Fire");
        if (canFire)        
        {
            Instantiate(projectile, firePoint.transform.position, firePoint.transform.rotation);
            PlaySound();
            PlayParticles();
            canFire = false;
            timer = 0;
        }
    }

    virtual public void PlaySound()     
    {
        if (soundClips.Count < 0)
        {
            audioSrc.clip = soundClips[Random.Range(0, soundClips.Count)];  
            audioSrc.Play();
        }
    }

    virtual public void PlayParticles()     
    {
        if (particles != null)
            particles.Play();

    }

}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class C4 : Weapon
{
    [SerializeField] float radius = 5f;
    List<GameObject> c4Placed = new List<GameObject>();

    void Start()
    {

    }

    public override void Update()
    {
        //base.Update();

        if (Input.GetKeyDown(KeyCode.Mouse0)) { //Fire Weapon (Left-click)
            this.Fire();
        }

        if (Input.GetKeyDown(KeyCode.Mouse1))    //Right Click
        {
            Place();
        }       //Left click is placing but no fire??????
    }       

    public override void Fire()
    {
        if (canFire)        //TODO: account for ammo        //canfire not based on timer but c4 placed < 0 (set interval to 0/low)
        {
            canFire = false;
            timer = 0;
            ExplodeAll();
        }
        Debug.Log("Called Override Fire");
    }

    public void Place()
    {
        Debug.Log("Called Place");
        //if (canFire)
        c4Placed.Add(Instantiate(projectile, firePoint.transform.position, firePoint.transform.rotation));    //Instantiate the c4 
        //on c4 have it move forward a tiny bit and attach to first surface it reaches
    }

    //Keep list of placed c4
    void ExplodeAll()
    {
        foreach(GameObject g in c4Placed)
        {
            g.GetComponent<C4Block>().Explode();     //Get c4 in place instead of the gameobject and use c4 list instead? (still reference gameobject when exploding)
            //play sound and particles for each c4
            //TODO: add explosive force
        }
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.