首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用开关实现简单的Unity3D巡防运动

用开关实现简单的Unity3D巡防运动
EN

Stack Overflow用户
提问于 2015-06-10 04:46:54
回答 3查看 952关注 0票数 1

我使用一个开关语句在敌人身上创建两种移动类型:前进和向后。敌人有三个巡逻点。当他开始时,我希望他从第一个巡逻点移动到当前点,当他到达第二个巡逻点(空3D游戏对象)时,添加1到当前点,等等。当他到达最后一点时,我会让他向相反的方向。

代码语言:javascript
复制
switch (moveType)
        {
        case MoveType.Forward:
            if (transform.position == patrolPoints[currentPoint].position)
            {
                currentPoint ++;
            }
            break;
        case MoveType.Backwards:
            if (transform.position == patrolPoints[patrolPointsLength].position)
            {
                currentPoint --;
            }
            break;
        }

问题是,我无法找到“触发”两个MoveTypes的方法。我如何编码这一点,以便当敌人击中他的最后巡逻点,他切换到MoveType.Backwards?我肯定我把这条路弄得比需要的更难。谢谢你的帮助!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-06-10 05:13:07

如果我真的想使用switch语句,我会这样做的:

代码语言:javascript
复制
    float someSmallValue = 0.5f; // Adjust this as per your needs

    if (Vector3.Distance(transform.position, patrolPoints[currentPoint].position) < someSmallValue)
    {
        switch (moveType)
        {
            case MoveType.Forward:
                currentPoint++;
                if (currentPoint > patrolPoints.Length - 1)
                {
                    currentPoint -= 1;
                    moveType = MoveType.Backwards;
                }
            break;

            case MoveType.Backwards:
                currentPoint--;
                if (currentPoint < 0)
                {
                    currentPoint = 1;
                    moveType = MoveType.Forward;
                }
            break;
        }

    }

我认为将currentPoint重命名为targetPoint将使这段代码的变量名更加清晰。

编辑:我忘了在向后的case块中减少currentPoint。更新了我的答案。

票数 1
EN

Stack Overflow用户

发布于 2015-06-10 06:21:39

我这里的解决方案增加了一些东西,比如暂停时间。它还确保快速移动的实体不会超过目的地,不会掉头或什么的。

代码语言:javascript
复制
// Movement speed normalized. So 1 is instantaneous travel and zero is no movement.
public float movementSpeed = 0.025;
// Let's add a 'pause' time where the unit waits a while at the turning point.
public float waitTime = 1;
// Lets say the list has 5 points.
public List<Vector3> patrolPoints ... 
// We keep track of our starting and ending points. Here we start at zero and move to position 1.
public Vector2 currentLeg = new Vector2(0,1);

// We use a coroutine
IEnumerator Patrol()
{
    // This keeps track of where we are. 0 is at the starting point and 1 is at the destination.
    float progress = 0;

    while(true)
    {
            Vector3 startingPoint = patrolPoints[currentLeg.x];
            Vector3 destination = patrolPoints[currentLeg.y];

            // Please note this won't compile. It's for brevity. You must lerp x,y,z indiviualy in C#.
            transform.position = Mathf.Lerp(startingPoint, destination, progress);
            progress+= movementSpeed;

            // If we are at our destination
            if(progress >=1 )
            {
                // Reset our progress so wa can start over.
                progress = 0;

                // Our current point is now what our destination was before.
                currentLeg.x = currentLeg.y;

                switch(moveType)
                {
                    case MoveType.Forward: 
                    {
                        // If this condition is true then it means we are at the final point (4 in this case). So we invert the movement direction and set the current point to 3.
                        if(currentLeg.y == patrolPoints.Count()-1)
                        {
                            currentLeg.y -= 1;
                            moveType = MoveType.Backwards;

                           // We wait 1 seconds and then do everything again.
                           yield return new WaitForSeconds(waitTime);
                        }
                        else
                            currentLeg.y++;
                    }
                    break;
                    case MoveType.Backward:
                    {
                        // If this condition is true then it means we are at the starting point (0). So we invert the movement direction and set the current point to 1.
                        if(currentLeg.y == 0)
                        {
                            currentLeg.y += 1;
                            moveType = MoveType.Forward;

                            // We wait 1 seconds and then do everything again.
                            yield return new WaitForSeconds(waitTime);
                        }
                        else
                            currentLeg.y--;
                    }
                    break;
                }

            }
    }
}

为了快速解决问题,杰森的回答会更好。但是,如果单元动作太快,或者如果动作太慢,它就会过早停止,它可能会失败。

编辑:等待时间在错误的地方。

票数 0
EN

Stack Overflow用户

发布于 2015-06-10 14:12:30

所以你想使用一个开关来巡逻,因为一次只能选择一个枚举?

为什么不使用一个public Transform target;变量,让您的AI始终遵循该变量中的内容?然后做一个空的游戏对象,并把它放入变量,他会跟随它,无论它去哪里。他不会被限制为“前进”和“向后”,当你想要将人工智能的代码循环到“左”到“右”的时候,你就不必重新编码或混淆了。

这将加快执行速度,清理代码,去除大量代码行,您还可以使用switch语句,因为这实际上将打开您的代码,使其具有更多的动态功能,例如:

代码语言:javascript
复制
public enum ActionType
{
    Patrol,
    Veer,
    Stop
}

假设他巡逻到目标的一半,他发现了一个敌人,ActionType curAction;可以设置为ActionType.Veer,现在他正在偏离巡逻线去攻击敌人,然后你可以把它放回ActionType.Patrol,然后他继续攻击目标。

因此,为了进行巡逻,您可以设置一个public List<Vector3> wayPoints;,并在其中添加一堆矢量3。当他到达目标时,他可以停一两秒钟,然后让空的游戏对象目标跳到列表中的下一个vector3。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30747296

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档