말감로그

[Unity] Valley - 동물 움직임 제어 본문

TIL

[Unity] Valley - 동물 움직임 제어

habbn 2024. 11. 19. 01:40
728x90

그래도 농장인데 플레이어와 나무만 있으면 심심할 것 같아 소를 하나 만들어서 울타리 안에서 자유자재로 이동시키는 작업을 하였다.

 

우선 소의 idle, walk 애니메이션을 만든 후, 스크립트를 생성하여 소의 랜덤 이동 방식을 구현하였다.

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEditor.Callbacks;
using UnityEngine;
using UnityEngine.UIElements;

public class Cow : MonoBehaviour
{
    public float walkSpeed = 1.2f;
    public float walkTime = 3f;
    public float idleTime = 2f;

    private Rigidbody2D rigid;
    private Animator anim;
    private SpriteRenderer sprite;
    private Vector2 direction;
    private float timer;
    private bool isWalking;

    void Start()
    {
        anim = GetComponent<Animator>();
        rigid = GetComponent<Rigidbody2D>();
        sprite = GetComponent<SpriteRenderer>();

        timer = walkTime;
        isWalking = true;
        ChooseRandomDirection();

    }

    void Update()
    {
        Debug.DrawRay(rigid.position, direction, Color.red);

        timer -= Time.deltaTime;

        if (isWalking)
        {
            RaycastHit2D rayHit = Physics2D.Raycast(rigid.position, direction, 1f, LayerMask.GetMask("Fence"));
            if (rayHit.collider != null)
            {
                rigid.velocity = Vector2.zero;
                anim.SetBool("isWalking", false);
                StopWalking();
                Invoke("ChooseRandomDirection", 2f);
            }
            else
            {
                rigid.velocity = direction * walkSpeed;
                anim.SetBool("isWalking", true);

                if (timer <= 0)
                {
                    StopWalking();
                }
            }
        }
        else
        {
            rigid.velocity = Vector2.zero;
            anim.SetBool("isWalking", false);

            if (timer <= 0)
            {
                StartWalking();
            }
        }
    }

    void StartWalking()
    {
        isWalking = true;
        timer = walkTime;
        ChooseRandomDirection();
    }

    void StopWalking()
    {
        isWalking = false;
        timer = idleTime;
    }

    void ChooseRandomDirection()
    {
        direction = new Vector2(Random.Range(-1f, 1f), Random.Range(-1f, 1f)).normalized;

        if (direction.x < 0)
        {
            sprite.flipX = true;
        }
        else
        {
            sprite.flipX = false;
        }
    }
}

 

Raycast를 통해 울타리를 인식하면 이동을 멈추고, 랜덤한 방향으로 다시 이동시키게끔 하였다. 그리고 그 방향에 맞게 sprite를 전환해주었다.

 

 

각 레이케스트를 통해 울타리를 인식하고, 멈추는 모습을 볼 수 있다!

728x90