简体   繁体   English

如何使用界面区分不同的对象

[英]How to distinguish between different objects using an interface

I'm creating a platform system using a raycast controller that uses an interface to perform different tasks based on the type of platform with which my player is currently colliding. 我正在使用光线投射控制器创建一个平台系统,该控制器使用一个接口根据播放器当前与之碰撞的平台类型执行不同的任务。 Some of the platform types include ice, passable blocks and muddy ground. 一些平台类型包括冰,可通过的块和泥泞的地面。

I want to know how to better optimize my code, as I currently call Unity's somewhat expensive "GetComponent()" function every frame, even if I never change between blocks. 我想知道如何更好地优化代码,因为我每帧都调用Unity有点昂贵的“ GetComponent()”函数,即使我从未在块之间切换也是如此。 What I'd like to do is only call GetComponent() when I change from one type of platform to a different type of platform (ie muddy ground --> ice), but don't know how to do this using an interface. 我只想从一种类型的平台更改为另一种类型的平台(例如,泥泞的地面->冰)时才调用GetComponent(),但不知道如何使用接口来执行此操作。

I thought I would be able to compare types using enums, but you're not allowed to declare types in an interface. 我以为我可以使用枚举来比较类型,但是不允许在接口中声明类型。

        if (hit)
        {
            //I'd only like to run this block of code if the type of platform changes
            var platform = hit.collider.gameObject.GetComponent<IPlatform>();

            State.IsCollidingWithPassablePlatform = platform.IsPassable;
            State.IsJumpBoosted = platform.IsJumpForce;
            State.IsBoosted = platform.IsForce;

            xForce = platform.XForce;
            yForce = platform.YForce;
            zForce = platform.ZForce;

            defaultParameters.accelerationTimeGrounded = platform.AccelerationTimeGrounded;
            defaultParameters.accelerationTimeAirborne = platform.AccelerationTimeAirborne;

Interface example: 接口示例:

interface IPlatform {

float AccelerationTimeGrounded { get; }
float AccelerationTimeAirborne { get; }

float XForce { get; }
float YForce { get; }
float ZForce { get; }

bool IsPassable { get; }

bool IsForce { get; }
bool IsJumpForce { get; }

Ice platform: 冰平台:

public class PlatformIce : MonoBehaviour, IPlatform {

public float AccelerationTimeGrounded { get { return accelerationTimeGrounded; } }
public float AccelerationTimeAirborne { get { return accelerationTimeAirborne; } }

public float XForce { get { return xForce; } }
public float YForce { get { return yForce; } }
public float ZForce { get { return zForce; } }

public virtual bool IsPassable { get { return false; } }

public bool IsForce { get { return false; } }
public bool IsJumpForce { get { return false; } }

[SerializeField]
private float accelerationTimeGrounded = 1.0f;
[SerializeField]
private float accelerationTimeAirborne = 3.0f;

private float xForce = 0;
private float yForce = 0;
private float zForce = 0;
}

Remember your last GameObject and check if this one has changed 记住您的最后一个游戏对象,并检查该对象是否已更改

private lastGameObj;
[...]
if(lastGameObj!= hit.collider.gameObject) {
var platform = hit.collider.gameObject.GetComponent<IPlatform>();
// [...] your magic here
lastGameObj= hit.collider.gameObject;
}

You will get an additional condition, but you won't run your code 60 times/sec inclusive that GetComponent();. 您将获得一个附加条件,但是您不会将代码运行60次(包括GetComponent();在内)每秒60次。

You CAN use enum s inside an Interface, you just have to declare the enum type outside the Interface. 您可以在接口内部使用enum ,只需在接口外部声明enum类型。

IE: IE:

public enum PlatformType {Normal, Ice, Fire, etc}; //Use public only if needed, of course

interface IPlatform {
    PlatformType platformType { get; }
    //Your other stuff here
}

This will break encapsulation, clearly, but if you really want to use an enum in an interface, there's no way around it. 显然,这将破坏封装,但是如果您真的想在接口中使用enum ,则enum

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM