在GameView中绘制线条

时间:2017-04-04 16:05:45

标签: c# unity3d unity5

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityStandardAssets.Characters.ThirdPerson;

public class WayPoints : MonoBehaviour {

    public GameObject[] waypoints;
    public Transform target;
    public float moveSpeed = 10f;
    public float moveSpeed1 = 10f;
    public float slowDownSpeed = 3f;
    public float reverseSlowDownSpeed = 3f;
    public float rotationSpeed = 1f;
    private Transform myTransform;
    private int targetsIndex = 0;
    private Vector3 originalPosition;
    private GameObject[] robots;

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

    public bool random = false;

    void Awake()
    {
        myTransform = transform;
    }
    // Use this for initialization
    void Start()
    {
        anims = GetComponent<Animations>();
        waypoints = GameObject.FindGameObjectsWithTag("ClonedObject");
        robots = GameObject.FindGameObjectsWithTag("Robots");

        foreach(GameObject go in waypoints)
        {
            go.isStatic = true;
        }
        UnityEditor.AI.NavMeshBuilder.BuildNavMesh();

        //AddColliderToWaypoints();
        originalPosition = robots[0].transform.position;
        reverseOriginalPosition = robots[1].transform.position;
    }

    // Update is called once per frame
    void Update()
    {
        if (MyCommands.walkbetweenwaypoints == true)
        {
            anims.PlayState(Animations.AnimatorStates.RUN);
            WayPointsAI();
            ReverseWayPointsAI();
        }

        DrawLinesInScene();
    }

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

        //move towards the player
        if (distance < 30)
        {
            robots[0].transform.position += robots[0].transform.forward * slowDownSpeed * Time.deltaTime;
        }
        else
        {
            robots[0].transform.position += robots[0].transform.forward * moveSpeed * Time.deltaTime;
        }
        if (distance < 2)
        {
            targetsIndex++;
        }
    }

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

        //move towards the player
        if (distance < 30)
        {
            robots[1].transform.position += robots[1].transform.forward * reverseSlowDownSpeed * Time.deltaTime;
        }
        else
        {
            robots[1].transform.position += robots[1].transform.forward * moveSpeed1 * Time.deltaTime;
        }
        if (distance < 2)
        {
            reverseTargetsIndex--;
        }
    }

    void RandomWayPointsAI()
    {
        if (random == true)
        {
            int index = 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, robots[0].transform.position, Color.red);
        Debug.DrawLine(reverseOriginalPosition, robots[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, robots[0].transform.position, Color.green);
        if (reverseTarget != null)
            Debug.DrawLine(reverseTarget.transform.position, robots[1].transform.position, Color.green);
    }

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

我可以在“场景”窗口中绘制显示路径路径的线条,在DrawLinesInScene函数中执行此操作。

但现在我想在游戏运行时在游戏窗口画出这些线条。在两侧的地形地面上制作一些闪烁的灯光,这样玩家就可以在它们之间行走。就像飞机降落在灯光之间一样。这种效果。

例如像这样的红灯:也许不会闪烁,但想法是显示像这样的航点路径。

lights

1 个答案:

答案 0 :(得分:2)

我写了一个LineDrawer辅助课程,取代了this帖子中的Debug.DrawLine。它适用于GameView。它具有与Debug.DrawLine相同的参数,并且还有一个如何在该帖子上使用它的示例。您可能需要增加该行的宽度。

仅仅画一条线是不够的,因为有一个晚上你需要一个GameObject和一个灯光。您还需要将GameObjects放在该行上。

假设这是一条直线,您可以使用以下函数将路径转换为卡盘路径:

void posToChunkDistances(Vector3 from, Vector3 to, Vector3[] result, int chunkAmount)
{
    //divider must be between 0 and 1
    float divider = 1f / chunkAmount;
    float linear = 0f;

    if (chunkAmount == 0)
    {
        Debug.LogError("chunkAmount Distance must be > 0 instead of " + chunkAmount);
        return;
    }

    if (chunkAmount == 1)
    {
        result[0] = Vector3.Lerp(from, to, 0.5f); //Return half/middle point
        return;
    }

    for (int i = 0; i < chunkAmount; i++)
    {
        if (i == 0)
        {
            linear = divider / 2;
        }
        else
        {
            linear += divider; //Add the divider to it to get the next distance
        }
        // Debug.Log("Loop " + i + ", is " + linear);
        result[i] = Vector3.Lerp(from, to, linear);
    }
}

使用此功能,您可以使用灯光形状(3D网格)实例化20个游戏对象,并在线条上均匀烘烤灯光。这应该是一个预制件。

public GameObject lightPrefab;

void Start()
{
    const int lightCount = 20;
    Vector3[] lightPositions = new Vector3[lightCount];
    posToChunkDistances(waypoints[0].transform.position, waypoints[waypoints.Length-1].transform.position , lightPositions, lightCount);

    for (int i = 0; i < lightPositions.Length; i++)
    {
        Instantiate(lightPrefab, lightPositions[i], Quaternion.identity);
    }
}

您还需要Lens Flares来获取问题中图片的效果。