[24.02.27]Unity - FlagPath

손지·2024년 2월 27일
0

Unity

목록 보기
17/44

어제와 똑같은 에셋을 세팅한다.

그리고 새로운 프리팹을 만들고 P_Flag로 이름을 지정해준 뒤 태그를 Flag 라고 새로 만들고 지정합니다.

그리고 Flag에 스크립트를 넣어둡니다.

Flag.cs

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

public class Flag : MonoBehaviour
{
    private MeshRenderer[] mrs = null;

    private void Awake()
    {
        mrs = GetComponentsInChildren<MeshRenderer>();
    }

    private void SetColors(Color _color)
    {
        foreach(MeshRenderer mr in mrs)
        {
            mr.material.SetColor("_Main", _color);
        }
    }

    public void SetSelectedColor()
    {
        SetColors(Color.yellow);
    }

    public void SetTouchedColor()
    {
        SetColors(Color.red);
    }

    public void ResetColor()
    {
        SetColors(Color.white);
    }

    public Vector3 GetPosition()
    {
        return transform.position;
    }

}

이런식으로 각 플래그가 갈수있는곳을 지정해주는 기능을 만드려고한다.

빈 오브젝트를 만들고 FlagPathManager 을 만들어 둡니다. 당연히 동일이름의 스크립트를 만들고 컴포넌트를 넣어줍니다.

그리고 임의로 아무데에나 Flag 프리팹을 만들어둔다

그리고 프리팹 설정 3DObject -> Text Mesh 를 만들면 깃발에 숫자를 구현할수 있다.

짠.

그리고 기존 치킨 프리팹을 가져와서 PathFinder이라는 이름으로 지정하고 스크립트를 만들어줍니다.

Ui-> Text Mesh Pro를 넣어주면 UI를 만들수 있습니다.

과제 : 최단거리,경로로 목표깃발을 찾아가는 알고리즘을 구현

FlagPathManager.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static UnityEngine.Texture2D;

public class FlagPathManager : MonoBehaviour
{
    [SerializeField] public PathFinder pathFinder = null;
    [SerializeField] private GUIPathList guiPathList = null;
    [SerializeField] public Flag startFlag = null;
    [SerializeField] public Flag tempFlag = null;
    [SerializeField] public Flag endFlag = null;
    [SerializeField] private Flag flag = null;

    private int i = 0;

    private void Awake()
    {
/*        startFlag = flag.nextFlags[i].transform.name;*/
        
    }

    public Flag[] PathFinding()
    {
        if(startFlag == null || endFlag == null)
        {
            return null;
        }
        //startFlag 부터 endFlag 까지 경로 탐색
        pathFinder.RaycastProcess(ref pathFinder.destination);
        return null;
    }

    private void Update()
    {

    }

}

Flag.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using TMPro;
using UnityEditor;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.UI;
using static Unity.IO.LowLevel.Unsafe.AsyncReadManagerMetrics;
using static UnityEditor.PlayerSettings;
public class Flag : MonoBehaviour
{
    [SerializeField] private int number = 0;
    [SerializeField] public Flag[] nextFlags = null;
    [SerializeField] public Flag[] flagName = null;
    [SerializeField] private bool onDebugMode = true;
    [SerializeField] private Color debugLineColor = Color.black;
    [SerializeField] private FlagPathManager flagPathManager = null;
    [SerializeField] private PathFinder pathFinder = null;
    private MeshRenderer[] mrs = null;
    private TextMeshPro numberText = null;
    private GameObject nowTransform = null;

    private MeshRenderer gos = null;
    private float[] dist = new float[100];
    private static float lastDist = 110;
    private string[] flagname = new string[1000];
    public bool stopMoving = false;

    private void Awake()
    {
        mrs = GetComponentsInChildren<MeshRenderer>();
        numberText = GetComponentInChildren<TextMeshPro>();
        gos = GetComponentInChildren<MeshRenderer>();


        for (int i = 0; i < 100; i++)
        {
            dist[i] = 0;
            Debug.Log(dist[i]);
        }

            /*        for (int i = 0; i < nextFlags.Length; i++)
                    {
                        Flag flag = nextFlags[i];
                        flagname[i] = transform.name;
                        startDist[i] = Vector3.Distance(transform.position, flag.transform.position);
                        Debug.Log(" Next Flag Name " + flag);
                    }*/


        }

    private void Start()
    {
        numberText.text = number.ToString();
/*
        for(int i = 0; i < nextFlags.Length; i++)
        {
            Debug.Log("Flagname : " + flagname[i] + " StadtDist : " + startDist[i]);
        }
*/

    }

    public int GetNumber()
    {
        return number;
    }
    private void SetColors(Color _color)
    {
        foreach(MeshRenderer mr in mrs)
        {
            mr.material.SetColor("_Main", _color);
        }
    }

    public void SetSelectedColor()
    {
        SetColors(Color.yellow);
    }

    public void SetTouchedColor()
    {
        SetColors(Color.red);
    }

    public void ResetColor()
    {
        SetColors(Color.white);
    }

    public Vector3 GetPosition()
    {
        return transform.position;
    }

    private void Update()
    {
        if (!onDebugMode) return;
        foreach (Flag flag in nextFlags)
        {
            Debug.DrawLine(transform.position, flag.GetPosition(), debugLineColor);
        }
        /* if (!pathFinder.isMoving)
         {
             if (flagPathManager.startFlag != null && flagPathManager.endFlag != null)
             {
                 if (flagPathManager.startFlag != flagPathManager.endFlag)
                 {
                     for (int i = 0; i < pathFinder.colliders.Length; i++)
                     {
                         if (flagPathManager.startFlag.transform.name == pathFinder.colliders[i].transform.name)
                         {
                             //Debug.Log("검출 : " + flagPathManager.tempFlag.name);
                             for (int j = 0; j < nextFlags.Length; j++)
                             {
                                 if (pathFinder.colliders[i].transform.name == nextFlags[j].transform.name)
                                 {
                                     Moving();
                                     //nextFlag 가 있으면 TempFlag에 저장하고 TempFlag 의 nextFlag가 endFlag와 같으면 동작.
                                 }
                                 else
                                 {
                                     Debug.Log("검출  : " + pathFinder.colliders[i].transform.name);
                                 }
                             }
                         }

                     }
                 }
             }
         }*/

        if (!pathFinder.isMoving && flagPathManager.startFlag != null && flagPathManager.endFlag != null && flagPathManager.startFlag != flagPathManager.endFlag)
        {
            for (int i = 0; i < pathFinder.colliders.Length; i++)
            {
                if (flagPathManager.startFlag.transform.name == pathFinder.colliders[i].transform.name)
                {
                    for (int j = 0; j < nextFlags.Length; j++)
                    {
                        if (pathFinder.colliders[i].transform.name == nextFlags[j].transform.name)
                        {
                            flagPathManager.tempFlag = transform.gameObject.GetComponent<Flag>();
                            for (int k = 0; k < nextFlags.Length; k++)
                            {
                                shortPath(k);
                            }
                            Debug.Log("LastDist검출  : " + lastDist);
                            Moving();
                        }
                    }
                }
            }
        }




    }


    private void OnTriggerEnter(Collider other)
    {
        if (gos != null)
        {
            gos = GetComponentInChildren<MeshRenderer>();
            MeshRenderer mr = gos.GetComponentInChildren<MeshRenderer>();
            mr.material.SetColor("_Color", Color.white);
        }
    }

    private bool Cal()
    {

        return true;
    }

    private void Moving()
    {

        if (Vector3.Distance(pathFinder.transform.position, flagPathManager.startFlag.transform.position) > 1f && stopMoving == false)
        {
            pathFinder.MovingToPoint(flagPathManager.startFlag.transform.position);
        }
        else
        {
            stopMoving = true;
            if (flagPathManager.endFlag.transform.gameObject.name == transform.name && stopMoving == true)
            {
                if (Vector3.Distance(pathFinder.transform.position, flagPathManager.endFlag.transform.position) > 1f)
                {
                    pathFinder.MovingToPoint(flagPathManager.endFlag.transform.position);
                }
            }
        }
    }

    private float shortPath(int k)
    {
        dist[k] = Vector3.Distance(pathFinder.transform.position, flagPathManager.tempFlag.transform.position) + Vector3.Distance(flagPathManager.tempFlag.transform.position, flagPathManager.endFlag.transform.position);
        if (dist[k] < lastDist)
        {
            lastDist = dist[k];

        }
        else if (dist[k] == lastDist)
        {
        
            Debug.Log("LastDist검출  : " + lastDist + "컴포넌트 : " + transform.name);
            pathFinder.MovingToPoint(transform.position);
            //pathFinder.MovingToPoint(flagPathManager.tempFlag.transform.position);
        }
        return lastDist;
    }

}

PathFinder.cs

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;
using static UnityEditor.Experimental.GraphView.GraphView;
using static UnityEditor.PlayerSettings;
using static UnityEngine.Texture2D;

public class PathFinder : MonoBehaviour
{

    [SerializeField] private float moveSpeed = 10f;
    [SerializeField] private float rotateSpeed = 10.0f;
    [SerializeField] private GameObject[] objs = null;
    [SerializeField] private Flag flags = null;
    [SerializeField] private FlagPathManager flagPathManager = null;


    private Flag[] pathList = null;
    private Camera mainCam = null;
    private Transform pointTr = null;
    private GameObject go = null;
    private Vector3 pointPos = Vector3.zero;
    private LayerMask layer;
    private int mask = (1 << 9);
    private int i = 0;


    public Collider[] colliders = null;
    public Collider flag;
    public Vector3 destination = Vector3.zero;
    public const float stopDistance = 1f;
    
    public bool isMoving = false;
    public float radius = 0;
  
    

    private void Update()
    {
        Serch();

        RaycastProcess(ref destination);
        Flag go = PickingProcessC();

        if (!isMoving & Input.GetMouseButton(0))
        {

            if (go != null)
            {
                flagPathManager.startFlag = PickingProcessC();
                transform.position = flagPathManager.startFlag.transform.position;
                SetColorAtGO(go, Color.green);
            }
        }

        if (!isMoving & Input.GetMouseButton(1))
        {

            if (go != null)
            {
                SetColorAtGO(go,Color.red);
                flagPathManager.endFlag = PickingProcessC();
            }   
        }
    }

    private void Serch()
    {
        if (flagPathManager.startFlag != null && flagPathManager.endFlag != null)
        {
            if (flagPathManager.startFlag != flagPathManager.endFlag)
            {
                colliders = Physics.OverlapSphere(transform.position, radius, mask);
                radius = (radius + 150);
            }
        }
    }

    public bool RaycastProcess(ref Vector3 _point)
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit, 100f, mask))
        {
            Debug.DrawRay(ray.origin, ray.direction * 100f, Color.blue);
            _point = hit.point;
            return true;
        }

        return false;
    }

    public Flag PickingProcessC()
    {
        mainCam = Camera.main;
        Vector3 mousePos = Input.mousePosition;
        mousePos.z = mainCam.nearClipPlane;
        Vector3 toWorld = mainCam.ScreenToWorldPoint(mousePos);
        Vector3 dir = (toWorld - mainCam.transform.position).normalized;
        RaycastHit hit;

        if (Physics.Raycast(mainCam.transform.position, dir, out hit, 100f, mask))
        {
            Flag flag = hit.transform.GetComponent<Flag>();
            if (flag != null)
            {
                return flag; 
            }
        }

        Debug.DrawRay(mainCam.transform.position, dir, Color.red);
        return null;
    }

    public void MovingToPoint(Vector3 _point)
    {
        
        _point.y = transform.position.y;
        Vector3 dir = _point - transform.position;
        dir.Normalize();
        transform.position = transform.position + (dir * moveSpeed * Time.deltaTime);
        if (Vector3.Distance(transform.position, _point) < stopDistance)
        {
            flagPathManager.startFlag = flagPathManager.tempFlag;
            isMoving = false;
        }
        transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(dir), Time.deltaTime * rotateSpeed);
    }

    private void StartMove(Flag[] _pathList)
    {
        if (pathList == null || pathList.Length == 0) { return; }
        pathList = _pathList;
    }
    public void SetColorAtGO(Flag _go, Color color)
    {
        MeshRenderer[] meshRenderers = _go.GetComponentsInChildren<MeshRenderer>();

        foreach (MeshRenderer mr in meshRenderers)
        {
            foreach (Material mat in mr.materials)
            {
                mat.SetColor("_Color", color);
            }
        }
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, radius);
    }
}
profile
게임 개발자가 될사람

0개의 댓글

관련 채용 정보