如何在航点之间随机移动玩家?

时间:2017-12-13 00:35:18

标签: c# unity3d unity5

我想要做的是,一旦随机标志为真,随机移动玩家在航点之间。 但只是调用随机方法是不够的。

using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class Waypoints : MonoBehaviour
{
    public GameObject[] waypoints;
    public Transform target;
    public float moveSpeed = 10f;
    public float slowDownSpeed = 3f;
    public float reverseSlowDownSpeed = 3f;
    public float rotationSpeed = 1f;
    private int targetsIndex = 0;
    private Vector3 originalPosition;
    private GameObject[] players;

    public Transform reverseTarget;
    private int reverseTargetsIndex = 0;
    private Vector3 reverseOriginalPosition;

    public bool random = false;

    // Use this for initialization
    void Start()
    {
        waypoints = GameObject.FindGameObjectsWithTag("Blocks");
        players = GameObject.FindGameObjectsWithTag("Player");
        originalPosition = players[0].transform.localPosition;
    }

    // Update is called once per frame
    void Update()
    {
        if (random == true)
        {
            RandomWayPointsAI();
        }
        else
        {
            WayPointsAI();
        } 
    }

    private void WayPointsAI()
    {
        if (targetsIndex == waypoints.Length)
            targetsIndex = 0;
        target = waypoints[targetsIndex].transform;
        float distance = Vector3.Distance(players[0].transform.position, target.transform.position);
        players[0].transform.localRotation = Quaternion.Slerp(players[0].transform.localRotation, Quaternion.LookRotation(target.position - players[0].transform.localPosition), rotationSpeed * Time.deltaTime);

        //move towards the player
        if (distance < 30)
        {
            players[0].transform.localPosition += players[0].transform.forward * slowDownSpeed * Time.deltaTime;
        }
        else
        {
            players[0].transform.localPosition += players[0].transform.forward * moveSpeed * Time.deltaTime;
        }
        if (distance < target.transform.localScale.magnitude)
        {
            targetsIndex++;
        }
    }

    private void ReverseWayPointsAI()
    {
        if (reverseTargetsIndex == 0)
            reverseTargetsIndex = waypoints.Length - 1;
        reverseTarget = waypoints[reverseTargetsIndex].transform;
        float distance = Vector3.Distance(players[1].transform.position, reverseTarget.transform.position);
        players[1].transform.rotation = Quaternion.Slerp(players[1].transform.rotation, Quaternion.LookRotation(reverseTarget.position - players[1].transform.position), rotationSpeed * Time.deltaTime);

        //move towards the player
        if (distance < 30)
        {
            players[1].transform.position += players[1].transform.forward * reverseSlowDownSpeed * Time.deltaTime;
        }
        else
        {
            players[1].transform.position += players[1].transform.forward * moveSpeed * Time.deltaTime;
        }
        if (distance < reverseTarget.transform.localScale.magnitude)
        {
            reverseTargetsIndex--;
        }
    }

    void RandomWayPointsAI()
    {
        if (random == true)
        {
            int index = UnityEngine.Random.Range(0, waypoints.Length);
            target = waypoints[index].transform;
        }
    }

    void DrawLinesInScene()
    {
        // draw lines between each checkpoint //
        for (int i = 0; i < waypoints.Length - 1; i++)
        {
            Debug.DrawLine(waypoints[i].transform.position, waypoints[i + 1].transform.position, Color.blue);
        }

        // draw a line between the original transform start position 
        // and the current transform position //
        Debug.DrawLine(originalPosition, players[0].transform.position, Color.red);
        Debug.DrawLine(reverseOriginalPosition, players[1].transform.position, Color.red);

        // draw a line between current transform position and the next waypoint target
        // each time reached a waypoint.
        if (target != null)
            Debug.DrawLine(target.transform.position, players[0].transform.position, Color.green);
        if (reverseTarget != null)
            Debug.DrawLine(reverseTarget.transform.position, players[1].transform.position, Color.green);
    }

    void AddColliderToWaypoints()
    {
        foreach (GameObject go in waypoints)
        {
            SphereCollider sc = go.AddComponent<SphereCollider>() as SphereCollider;
            sc.isTrigger = true;
        }
    }
}

在更新内部我正在检查random是否为true然后调用RandomWayPointsAI();但它并没有移动玩家,只是不断地为每一帧拾取一个新的随机航点,但就是这样。

void Update()
    {
        if (random == true)
        {
            RandomWayPointsAI();
        }
        else
        {
            WayPointsAI();
        } 
    }

2 个答案:

答案 0 :(得分:1)

如果你看看你的RandomWayPointsAI()函数,它只定义索引和目标,但不要在它下面有任何代码来移动玩家。

private void WayPointsAI()
{
    if (targetsIndex == waypoints.Length)
        targetsIndex = 0;
    target = waypoints[targetsIndex].transform;
    float distance = Vector3.Distance(players[0].transform.position, target.transform.position);
    players[0].transform.localRotation = Quaternion.Slerp(players[0].transform.localRotation, Quaternion.LookRotation(target.position - players[0].transform.localPosition), rotationSpeed * Time.deltaTime);


void RandomWayPointsAI()
{
    //No need to check if random is true anymore, you already checked when you run this function
    int index = UnityEngine.Random.Range(0, waypoints.Length);
    target = waypoints[index].transform;
    //float distance = Vector3.Distance(players[0].transform.position, target.transform.position);
    //players[0].transform.localRotation = Quaternion.Slerp(players[0].transform.localRotation, Quaternion.LookRotation(target.position - players[0].transform.localPosition), rotationSpeed * Time.deltaTime);**
}

答案 1 :(得分:1)

这是你的答案。首先,你不是在随机函数中编写运动代码,而是期望它移动。

bool getNextRandom = true;
void RandomWayPointsAI()
{
    if (random == true && getNextRandom)
    {
        int index = UnityEngine.Random.Range(0, waypoints.Length);
        target = waypoints[index].transform;
        getNextRandom = false;
    }
    float distance = Vector3.Distance(players[0].transform.position, target.transform.position);
    players[0].transform.localRotation = Quaternion.Slerp(players[0].transform.localRotation, Quaternion.LookRotation(target.position - players[0].transform.localPosition), rotationSpeed * Time.deltaTime);

    //move towards the player
    if (distance < 30)
    {
        players[0].transform.localPosition += players[0].transform.forward * slowDownSpeed * Time.deltaTime;
    }
    else
    {
        players[0].transform.localPosition += players[0].transform.forward * moveSpeed * Time.deltaTime;
    }
    if (distance < target.transform.localScale.magnitude)
    {
        getNextRandom = true;
    }
}

此外,您可以通过将移动代码移动到另一个可以更好地控制的功能来改进解决方案

public GameObject[] waypoints;
public Transform target;
public float moveSpeed = 10f;
public float slowDownSpeed = 3f;
public float reverseSlowDownSpeed = 3f;
public float rotationSpeed = 1f;
private int targetsIndex = 0;
private Vector3 originalPosition;
private GameObject[] players;
public Transform reverseTarget;
private int reverseTargetsIndex = 0;
private Vector3 reverseOriginalPosition;
public bool random = false;
public bool getNextRandom = true;

// Use this for initialization
void Start()
{
    waypoints = GameObject.FindGameObjectsWithTag("Blocks");
    players = GameObject.FindGameObjectsWithTag("Player");
    originalPosition = players[0].transform.localPosition;
}

// Update is called once per frame
void Update()
{
    if (random == true)
    {
        RandomWayPointsAI();
    }
    else
    {
        WayPointsAI();
    }
}

private void WayPointsAI()
{
    if (targetsIndex == waypoints.Length)
        targetsIndex = 0;
    target = waypoints[targetsIndex].transform;

    if (MovePlayer())
        targetsIndex++;
}

private void ReverseWayPointsAI()
{
    if (reverseTargetsIndex == 0)
        reverseTargetsIndex = waypoints.Length - 1;
    reverseTarget = waypoints[reverseTargetsIndex].transform;

    if (MovePlayer())
        reverseTargetsIndex--;
}


void RandomWayPointsAI()
{
    if (random == true && getNextRandom)
    {
        int index = UnityEngine.Random.Range(0, waypoints.Length);
        target = waypoints[index].transform;
        getNextRandom = false;
    }
    getNextRandom = MovePlayer();
}

bool MovePlayer()
{
    float distance = Vector3.Distance(players[0].transform.position, target.transform.position);
    players[0].transform.localRotation = Quaternion.Slerp(players[0].transform.localRotation, Quaternion.LookRotation(target.position - players[0].transform.localPosition), rotationSpeed * Time.deltaTime);

    //move towards the player
    if (distance < 30)
    {
        players[0].transform.localPosition += players[0].transform.forward * slowDownSpeed * Time.deltaTime;
    }
    else
    {
        players[0].transform.localPosition += players[0].transform.forward * moveSpeed * Time.deltaTime;
    }
    if (distance < target.transform.localScale.magnitude)
        return true;
    else
        return false;

}

void DrawLinesInScene()
{
    // draw lines between each checkpoint //
    for (int i = 0; i < waypoints.Length - 1; i++)
    {
        Debug.DrawLine(waypoints[i].transform.position, waypoints[i + 1].transform.position, Color.blue);
    }

    // draw a line between the original transform start position 
    // and the current transform position //
    Debug.DrawLine(originalPosition, players[0].transform.position, Color.red);
    Debug.DrawLine(reverseOriginalPosition, players[1].transform.position, Color.red);

    // draw a line between current transform position and the next waypoint target
    // each time reached a waypoint.
    if (target != null)
        Debug.DrawLine(target.transform.position, players[0].transform.position, Color.green);
    if (reverseTarget != null)
        Debug.DrawLine(reverseTarget.transform.position, players[1].transform.position, Color.green);
}

void AddColliderToWaypoints()
{
    foreach (GameObject go in waypoints)
    {
        SphereCollider sc = go.AddComponent<SphereCollider>() as SphereCollider;
        sc.isTrigger = true;
    }
}