Rod*_*ian 3 c# inheritance function unity-game-engine
我创建了一个父类,我希望它具有与测试 GameObject 是否接地、在水中、在空气中等相关的所有功能……鉴于此功能将被玩家以及其他 GameObjects 使用。但是,子类似乎没有正确继承这些功能。
父脚本如下:
public class CharacterPhysic : MonoBehaviour {
[SerializeField] protected Transform groundPoints;
float grounRadius;
private void Start ()
{
whatIsGround = LayerMask.GetMask("Ground");
groundRadius = 0.01f;
}
protected bool IsGrounded()
{
Collider2D[] colliders = Physics2D.OverlapCircleAll(groundPoints.position, groundRadius, whatIsGround);
if (colliders.Length > 0)
{
return true;
}
else return false;
}
private void FixedUpdate()
{
Debug.Log(IsGrounded());
}
}
Run Code Online (Sandbox Code Playgroud)
而儿童脚本只是:
public class ErrantMove : CharacterPhysic {
private void FixedUpdate()
{
Debug.Log(IsGrounded());
}
}
Run Code Online (Sandbox Code Playgroud)
当将第一个脚本作为组件添加到游戏对象时(在定义了 grounPoint 之后)Debug.Log(IsGrounded());返回TRUE
但是,当将第二个脚本作为组件添加到同一个游戏对象时(在定义了 grounPoint 并删除了第一个脚本之后),即使在相同的情况下也会Debug.Log(IsGrounded());返回FALSE。
我希望能够将移动功能添加到第二个脚本中,但这取决于测试它是否接地的能力。
你可以适当地继承Unity的回调函数,例如Awake,Start 和Update你一样会与一个普通的C#的继承模式。这很简单。
使基类的所有回调函数为virtual:
public class YourBaseClass : MonoBehaviour
{
protected virtual void Awake()
{
Debug.Log("Awake Base");
}
protected virtual void Start()
{
Debug.Log("Start Base");
}
protected virtual void Update()
{
Debug.Log("Update Base");
}
protected virtual void FixedUpdate()
{
Debug.Log("FixedUpdate Base");
}
}
Run Code Online (Sandbox Code Playgroud)
对于将从基类派生的父类,也添加回调函数,但将它们标记为override. 如果您需要调用基函数,请base.FunctionName在父函数中执行任何其他操作之前调用它:
public class Parent : YourBaseClass
{
protected override void Awake()
{
base.Awake();
Debug.Log("Awake Parent");
}
protected override void Start()
{
base.Start();
Debug.Log("Start Parent");
}
protected override void Update()
{
base.Update();
Debug.Log("Update Parent");
}
protected override void FixedUpdate()
{
base.FixedUpdate();
Debug.Log("FixedUpdate Parent");
}
}
Run Code Online (Sandbox Code Playgroud)
您的Start方法不会在子类中执行。如果您不打算使用父类,请将其移至子类中。
public class ErrantMove : CharacterPhysic {
protected void Start ()
{
whatIsGround = LayerMask.GetMask("Ground");
groundRadius = 0.01f;
}
private void FixedUpdate()
{
Debug.Log(IsGrounded());
}
}
Run Code Online (Sandbox Code Playgroud)
您可以注意到,如果您有多个子类,您将被迫Start在每个子类中初始化基类的方法,因此您可以创建一个virtual Start方法,然后在子类中调用它:
public class CharacterPhysic : MonoBehaviour {
. . .
protected virtual void Start ()
{
whatIsGround = LayerMask.GetMask("Ground");
groundRadius = 0.01f;
}
protected bool IsGrounded()
{
Collider2D[] colliders = Physics2D.OverlapCircleAll(groundPoints.position, groundRadius, whatIsGround);
return colliders.Length > 0;
}
. . .
}
public class ErrantMove : CharacterPhysic {
protected override void Start()
{
base.Start();
}
private void FixedUpdate()
{
Debug.Log(IsGrounded());
}
}
Run Code Online (Sandbox Code Playgroud)
您可以采用任一virtual/override方法,或使用new关键字“取消隐藏”子类的Start方法(我不确定new统一的行为如何,所以最好使用第一个方法)。