在 Unity 中,如何在使用 Instantiate() 方法如带参数的 OOP 构造函数初始化预制件时为属性设置值?

问题描述

我是 Unity 和游戏开发的新手。我想用原语制作一个移动堆栈跳跃游戏。我在屏幕中央有一个播放器。敌人正在从屏幕的右侧和左侧接近玩家。玩家试图通过跳跃来坐在敌人身上,就像在马里奥游戏中一样。如果敌人从侧面击中玩家,则游戏结束。我用 SpawnMan 创建敌人。有一个敌人游戏对象的预制件。 SpawnMan 使用 Instantiate() 方法以特定时间间隔创建它们。我想存储有关敌人是从右侧还是左侧接近的数据。我什至想通过创建枚举类型来存储这些信息。总之,我想拥有左右类型的敌人对象。当在带有参数的 OOP 构造函数中调用 SpawnMan 中的 Instantiate() 方法时,如何设置此属性(左敌人或右敌人)。

enum EnemyType
{
    Left,Right
}

// ...
    
Instantiate(enemyPrefab(EnemyType.Left),spawnPos,enemyPrefab.transform.rotation);

解决方法

首先实例化时分配一个游戏对象: 游戏对象敌人 1 = 实例化(...) 那么,我们可以使用玩家变换和敌人变换向量来获得一个方向(+值和负值)?

,

正如 Chandradhar 所说,除此之外,您还可以使用 Mathf.Sign(player.position.x-敌人.position.x);查看敌人是来自玩家的左侧还是右侧。

,

你不能完全以这种方式传递它,因为 Instantiate 不会在实例化的预制件的脚本上调用构造函数。或者我猜敌对预制可能是一种返回具有设置脚本值的实际预制对象的方法,但这将是一种获得您想要的东西的奇怪方式。

但大概你只是想让敌人的对象有关于左/右的信息,在这种情况下,最简单的方法是获取附加的脚本,然后分配左/右属性。所以你可以在你的敌人脚本中添加这样的东西(附加到敌人预制件的那个)

public class MyEnemyScript : MonoBehaviour
{
    public EnemyType Type;
    
    ... your enemy code here...
}

然后像这样使用它:

var enemyGameObj = Instantiate(enemyPrefab,spawnPos,enemyPrefab.transform.rotation);
enemyGameObj.GetComponent<MyEnemyScript>().Type = EnemyType.Left;

请注意,这不是一个很好的做法,因为 GetComponent 是一个昂贵的调用,但同样也不是实例化所有这些敌人 - 使用池化会更好。

,

我假设左和右的枚举是矫枉过正的,但如果你有一些设计原因,敌人需要根据他们站在哪一边有一些特殊的逻辑,你仍然可以用更简单的方式处理它时尚。

在您的 MyEnemyScript() 中,您有 Awake()OnEnable() 方法,它们将被 Unity 自动调用,就像 StartUpdate 一样。在其中之一(如果您使用对象池,请使用 OnEnable),输入如下内容:

public EnemyType type;
private void Awake()
{
    if (transform.position.x > PlayerInfo.playerPosition.x)
        type = EnemyType.right;
    else
        type = EnemyType.left;
}

现在你可以不假思索地照常生成敌人。 PlayerInfo 可以是静态类或单例,也可以是您希望使该信息可用的任何方式。

然后在您的更新循环中,只有两个逻辑路径(我认为这与您所做的类似)。

private void Update()
{
    if(type = EnemyType.left)
        //do left enemy stuff
    else
        //do right enemy stuff
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...