如何避免每帧进行类型检查?

时间:2019-07-12 21:19:48

标签: c# unity3d types

我正在编写一个车辆控制器,该控制器应该能够处理多种不同的车辆类型,而不是使用继承,因此我可以将类的数量降至最低。我想删除检查每个固定帧的常量类型,但是我不确定该怎么做。

private void FixedUpdate()
{
    if (VehicleSchema is VehicleSchema_AFV.Hovercraft)
    {
        UpdatePosition(transform.forward, false);
        UpdateYawRotation(false);
        AlignToTerrain(false, false);

        VehicleSchema_AFV afv = (VehicleSchema_AFV)VehicleSchema;
        UpdateTurretRotation(afv.TurretObj);
    }
    else if (VehicleSchema is VehicleSchema_AFV.Wheeledcraft)
    {
        UpdatePosition(transform.forward, false);
        UpdateYawRotation(true);
        AlignToTerrain(true, true);

        VehicleSchema_AFV afv = (VehicleSchema_AFV)VehicleSchema;
        UpdateTurretRotation(afv.TurretObj);
    }
    else if (VehicleSchema is VehicleSchema_AFV.Trackedcraft)
    {
        UpdatePosition(transform.forward, false);
        UpdateYawRotation(false);
        AlignToTerrain(true, false);

        VehicleSchema_AFV afv = (VehicleSchema_AFV)VehicleSchema;
        UpdateTurretRotation(afv.TurretObj);
    }
    else if (VehicleSchema is VehicleSchema_Mech)
    {
        UpdatePosition(transform.forward, false);
        UpdateYawRotation(false);
        AlignToTerrain(true, false);

        VehicleSchema_Mech mech = (VehicleSchema_Mech)VehicleSchema;
        UpdateTurretRotation(mech.TorsoObject);
    }
    else if (VehicleSchema is VehicleSchema_Aircraft.VTOL)
    {
        UpdatePosition(transform.up, true);
        UpdateYawRotation(false);
        UpdatePitchRotation();
        UpdateRollRotation();

        VehicleSchema_Aircraft.VTOL vtol = (VehicleSchema_Aircraft.VTOL)VehicleSchema;
        UpdateTurretRotation(vtol.TurretObj);
    }
}

2 个答案:

答案 0 :(得分:2)

使用某些多态性怎么样?

只需声明一个代表可更新车辆的接口

interface IUpdatableVehicle
{
    void Update();
}

然后让您的类使用各自的逻辑来实现此接口

class Hovercraft : IUpdatableVehicle
{
    public void Update()
    {
        UpdatePosition(transform.forward, false);
        UpdateYawRotation(false);
        AlignToTerrain(false, false);

        VehicleSchema_AFV afv = (VehicleSchema_AFV)VehicleSchema;
        UpdateTurretRotation(afv.TurretObj);
    }
}

class Wheeledcraft : IUpdatableVehicle
{
    public void Update()
    {
        UpdatePosition(transform.forward, false);
        UpdateYawRotation(true);
        AlignToTerrain(true, true);

        VehicleSchema_AFV afv = (VehicleSchema_AFV)VehicleSchema;
        UpdateTurretRotation(afv.TurretObj);
    }
}

// And so on ...

最后,在更新功能中使用一条指令

private void FixedUpdate(IUpdatableVehicle vehicle) {
    vehicle.Update();
}

现在,如果UpdatePositionUpdateYawRotation等在上下文之外可用(我对Unity不熟悉),或者您是否有权使用base课,所以我认为是这种情况。如果不是,则可能需要在原始问题中添加这些精度。

答案 1 :(得分:0)

再次感谢亚瑟(Arthur)为解决此问题所提供的帮助。由于程序的结构,我不得不稍微修改Arthur的解决方案以使其正常工作。但是,如果其他人在旅途中遇到类似情况,我想为他们发布信息。

界面

ConditionalAttribute

基类

public interface IUpdatableVehicle
{
    void UpdateWorldState();
}

子类

public abstract class VehicleSchema : MonoBehaviour, IUpdatableVehicle
{

//Properties
//========================================================================================================================//

public VehicleController VehicleCtrler { get; protected set; }

//Methods
//========================================================================================================================//

private void Awake()
{
    VehicleCtrler = gameObject.AddComponent<VehicleController>();
    gameObject.AddComponent<VehicleInputController_Player>();
}

//Abstract Methods
//========================================================================================================================//

public abstract void UpdateWorldState();
}

}

控制器

public abstract class VehicleSchema_AFV : VehicleSchema
{

//Sub AFV Classes
//========================================================================================================================//

public abstract class Hovercraft : VehicleSchema_AFV
{
    public override void UpdateWorldState()
    {
        VehicleCtrler.UpdatePosition(transform.forward, false);
        VehicleCtrler.UpdateYawRotation(false);
        VehicleCtrler.AlignToTerrain(false, false);

        VehicleCtrler.UpdateTurretRotation(TurretObj);
    }
}

public abstract class Trackedcraft : VehicleSchema_AFV
{
    public override void UpdateWorldState()
    {
        VehicleCtrler.UpdatePosition(transform.forward, false);
        VehicleCtrler.UpdateYawRotation(false);
        VehicleCtrler.AlignToTerrain(true, false);


        VehicleCtrler.UpdateTurretRotation(TurretObj);
    }
}

public abstract class Wheeledcraft : VehicleSchema_AFV
{
    public override void UpdateWorldState()
    {
        VehicleCtrler.UpdatePosition(transform.forward, false);
        VehicleCtrler.UpdateYawRotation(true);
        VehicleCtrler.AlignToTerrain(true, true);

        VehicleCtrler.UpdateTurretRotation(TurretObj);
    }
}