我對繼承有基本的了解,但是由于我想要作為游戲物件上的組件的每個腳本都必須從 MonoBehaviour 繼承,所以事情變得很棘手。
假設我想要一個名為 Character 的基類,并且我希望 Player 和 Enemy 派生自 Character。我應該如何將 Player 和 Enemy 腳本添加到 Player 和 Enemy 物件而不會出錯?
我還嘗試創建空游戲物件并向其添加 CharacterStats,然后使用具有不同統計資訊的不同角色物件填充此類。你猜怎么著,如果腳本派生自 Monobehaviour,你就不能使用 new 關鍵字來創建物件。
有沒有關于這個主題的教程讓它更清楚?
uj5u.com熱心網友回復:
可能要理解的是它MonoBehaviour本身繼承Component了 - MonoBehaviour 是一個組件。
當您將其視為組件是事物的一部分時,至少在某種意義上說您不能只是new一個組件-我可以做一個new Arm嗎?如果我這樣做了,它會在哪里?但我可以先做一個new Body body然后做body.AddComponent<Arm>,對吧?因為那時很清楚手臂會發生什么 - 它附著在身體上。
同樣,您不能只是new一個組件,因為它們應該是游戲物件的一部分。您可以做的是創建一個新的 GameObject 和.AddComponent<>()該物件。同樣,現在很清楚該組件的去向。
我通常同意UnholySheep 的評論,即您應該更喜歡組合而不是繼承,因為這通常會使您的代碼更加模塊化。也就是說,我肯定也使用繼承。
當你概述你的班級時,你應該問自己的問題是,“這個新班級是_____還是這個新班級有____。” 我想很容易說玩家是角色,敵人是角色,但是你需要子類化嗎?或者玩家只是一個也有 PlayerController 的角色?也許你可以有一個像IPlayerController用戶LocalPlayerController和AIPlayerController敵人一樣的界面?用編程解決問題的方法很多。
或者,也許所有角色都有一個 PlayerController,而.activeControl對于非玩家角色,只有這一位是錯誤的。然后你可以做鬼/旁觀 NPC 之類的事情。
但具體到你的問題:
假設我想要一個名為 Character 的基類,并且我希望 Player 和 Enemy 派生自 Character。我應該如何將 Player 和 Enemy 腳本添加到 Player 和 Enemy 物件而不會出錯?
您將從一個Character繼承 MonoBehaviour 并實作兩個類共有的邏輯的腳本開始:
public class Character : MonoBehaviour
{
// Your common character logic
}
然后你會有子類繼承Character:
public class Player : Character
{
// Your Player-specific logic here
}
和
public class Enemy : Character
{
// Your Enemy-specific logic here
}
然后,您可以在編輯器中將Enemy和Player腳本添加到游戲物件,或者您可以通過獲取對目標游戲物件的參考(通過在編輯器中設定參考或在腳本中創建新游戲物件)以編程方式執行此操作,然后呼叫targetGameObject.AddComponent<YourComponentToAdd>();.
uj5u.com熱心網友回復:
很好地使用繼承來自計劃和迭代。也許您的 Character 課程不能很好地作為您的敵人的課程。我傾向于讓玩家在他們自己的類中(除非它的多人游戲),而敵人使用他們自己的基類。下面是我在正在開發的 2D 游戲中使用的一些繼承示例。
基類: Enemy.cs
public abstract class Enemy : MonoBehaviour
{
public Vector2 flyInPos;
public Vector2 startPos;
public bool isFlyingIn;
public float flyInDuration = 5000f;
public float flyInTime = 0f;
public abstract void Destroy();
public abstract void DestroyWithoutScore();
public abstract void Attack();
public abstract void Attack2();
public abstract void Attack3();
public abstract void FlyOut();
public virtual void FlyIn()
{
isFlyingIn = true;
}
}
每個敵人都需要擁有這些元素。您會注意到我的基類中的大多數方法都被標記為抽象,因此每個繼承的類都可以有一組獨特的攻擊和飛行模式。需要注意的一件事是基類繼承自 MonoBehaviour。以下是我如何在我的一個敵人中實作繼承。抱歉,它仍然是 WIP。
繼承類: ShootingDrone.cs
public class ShootingDrone : Enemy
{
public GameObject projectileSpawner;
public GameObject projectile;
public void Start()
{
startPos = transform.position;
Scheduler.Invoke(Attack, 5f, gameObject);
}
public void Update()
{
if(isFlyingIn)
{
transform.position = Vector3.Lerp(startPos, flyInPos, flyInTime / flyInDuration);
flyInTime = Time.deltaTime;
}
}
public override void Attack()
{
Shoot();
Scheduler.Invoke(Shoot, 0.25f, gameObject);
Scheduler.Invoke(Shoot, 0.5f, gameObject);
}
public override void Attack2()
{
Attack();
}
public override void Attack3()
{
Attack();
}
public void Shoot()
{
GameObject newProjectile = Instantiate(projectile, projectileSpawner.transform);
newProjectile.transform.parent = null;
}
public override void FlyOut()
{
throw new System.NotImplementedException();
}
public override void DestroyWithoutScore()
{
throw new System.NotImplementedException();
}
public override void Destroy()
{
Destroy(gameObject);
}
}
Enemy的基類繼承自 MonoBehaviour。因此,當Shooting Drone繼承自Enemy時,它也繼承自 MonoBehaviour。
對于您嘗試添加新的 MonoBehaviour 的問題。這樣做的原因是 MonoBehavior 必須附加到某些東西上。想象一個沒有游戲物件的剛體,它不起作用。如果您想按照以下方式制作“新” CharacterStats:
CharacterStats stats = gameObject.AddComponent<CharacterStats>();
如果您不希望將 CharacterStats 作為組件,則只需從類中洗掉 MonoBehavior 繼承并將其實體化為新的 CharacterStats。
有很多關于繼承的教程,但是根據你對這個主題的了解程度,我會從Unity 官方繼承教程開始。我確實認為本教程太簡短了,但我也喜歡CircutStreams 教程,因為它還提到了實作介面,這在許多情況下可以成為更好的繼承解決方案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/467030.html
