在我的游戏中,有武器管理器(交换武器),武器脚本(具有射击方法的武器的基类)和武器。
我将射击代码从武器管理员转移到了武器本身。但是现在我已经覆盖了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
}
}
}
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
}
}
}