我目前正在Unity中创建一个游戏,我想创建一个法术系统。为此,我创建了一个名为ISpell的接口,目前只有一个方法(castSpell)。我还创建了一个名为Fireball的法术,它实现了ISpell接口,允许玩家发射火球。
我的问题如下:我有一个名为能力的职业附加到我的玩家身上,它的唯一目的就是定义启动法术的钥匙,并选择玩家拥有的法术(这对我的问题并不重要)和每个法术的两个属性,第一个属性对应的是启动法术的钥匙,第二个是ISpell类型的属性,不过我无法拖放我的火球术法术,因为该属性不会出现在Unity检查器中,即使它已声明为公共属性。
我不知道我的解决方案是否可行,但我想为我的游戏创建一个灵活且可定制的法术系统。
先谢谢你!以下是我的课程:
public interface ISpell {
void castSpell(Transform spawnPoint);
float getSpellSpeed();
float getSpellLifetime();
float getSpellCooldown();
}
public class FireballSpell : MonoBehaviour, ISpell {
[Header("Spell Base Settings")]
public float SpellSpeed = 2.0f;
public float projectileLifeTime = 10.0f;
public float cooldown = 1.0f;
public GameObject spellPrefab;
[Header("Explosion Settings")]
public float explosionRadius = 10.0f;
public GameObject explosionEffect;
private Vector3 startScale;
void Start()
{
Destroy(gameObject, projectileLifeTime);
startScale = explosionEffect.transform.localScale;
}
public void castSpell(Transform spawnPoint)
{
GameObject spellClone = Instantiate(spellPrefab, spawnPoint.position, spawnPoint.rotation);
Rigidbody rb = spellClone.GetComponent<Rigidbody>();
rb.AddForce(spawnPoint.forward * spellClone.GetComponent<ISpell>().getSpellSpeed(), ForceMode.Impulse);
}
void Destroyed(){
Destroy(gameObject);
}
void OnDestroy()
{
Explode();
}
private void OnTriggerEnter(Collider other)
{
if(other.tag == "Player"){
return;
} else {
Destroy(gameObject);
}
}
public void Explode(){
Vector3 v = new Vector3(explosionRadius, explosionRadius, explosionRadius);
Instantiate(explosionEffect, transform.position, transform.rotation);
explosionEffect.transform.localScale = v;
Collider[] colliders = Physics.OverlapSphere(transform.position, explosionRadius);
foreach (Collider nearbyObject in colliders)
{
if(nearbyObject.tag == "Player" || nearbyObject.tag == "Enemy"){
Rigidbody rb = nearbyObject.GetComponent<Rigidbody>();
/**Health health = nearbyObject.GetComponent<Health>();
if (health != null)
{
health.TakeDamage(damage);
}**/
if(nearbyObject.tag == "Enemy"){
}
}
}
}
private void OnDrawGizmosSelected(){
Gizmos.DrawWireSphere(this.transform.position, explosionRadius);
}
public float getSpellSpeed(){
return SpellSpeed;
}
public float getSpellLifetime(){
return projectileLifeTime;
}
public float getSpellCooldown(){
return cooldown;
}
}
public class Abilities: MonoBehaviour {
public Transform spawnPoint;
[Header("Spell 1 Settings")]
public ISpell spell1;
public KeyCode key1;
void Update()
{
if(Input.GetKeyDown(key1))
{
spell1.castSpell(spawnPoint);
}
}
}
1条答案
按热度按时间kninwzqo1#
Unity默认不能序列化接口,可以使用Odin来实现,但实际上我并不推荐。
如果你想在检查器窗口中分配链接,你可以使用一个小技巧。只需将你的
ISpell
接口替换为基本抽象MonoBehaviour
类。然后你就可以在检查器中分配这个链接。