TIL
20231205 TIL / 게임개발 / 오브젝트 움직임
도도9999
2023. 12. 5. 09:46
그동안 이것저것 많은것을 추가, 수정했다.
기존에 NPC들이 화면에 단발적으로 띡띡 등장했는데 이것을 자연스럽게 수정하고자 왼쪽에서부터 자연스럽게 나오도록 수정했다.
using UnityEngine;
public class NPCMovement : MonoBehaviour
{
public float speed = 1.0f;
public Vector3 startPositionOffScreen = new Vector3(-100, 0, 0);
public Vector3 centerScreenPosition = new Vector3(0, 0, 0);
public Vector3 endPositionOffScreen = new Vector3(-100, 0, 0);
private Transform _transform;
private Animator animator;
private Vector3 targetPosition;
public Transform visualRepresentation;
private float arrivalThreshold = 0.1f;
private void Awake()
{
_transform = GetComponent<Transform>();
animator = GetComponent<Animator>();
}
public void OnEnable()
{
SetStartPosition();
MoveToCenter();
ResetDirection();
}
private void Update()
{
_transform.position = Vector3.MoveTowards(_transform.position, targetPosition, speed * Time.deltaTime);
animator.SetBool("isWalking", _transform.position != targetPosition);
if (Vector3.Distance(_transform.position, targetPosition) < arrivalThreshold)
{
OnReachedDestination();
}
}
private void MoveToCenter()
{
SetTargetPosition(centerScreenPosition);
}
public void WalkOutOfScreen()
{
SetTargetPosition(endPositionOffScreen);
}
public void SetStartPosition()
{
_transform.position = startPositionOffScreen;
}
private void OnReachedDestination()
{
animator.SetBool("isWalking", false);
if (targetPosition == centerScreenPosition)
{
}
else if (targetPosition == endPositionOffScreen)
{
gameObject.SetActive(false);
}
}
private void OnDisable()
{
ResetDirection();
}
public void TurnAround()
{
if (_transform.eulerAngles.y != -180)
{
Vector3 rotation = _transform.eulerAngles;
rotation.y = -180; // Y축 기준 -180도 회전
_transform.eulerAngles = rotation;
}
}
private void ResetDirection()
{
if (_transform.eulerAngles.y != 0)
{
Vector3 rotation = _transform.eulerAngles;
rotation.y = 0; // Y축을 0도로 리셋
_transform.eulerAngles = rotation;
}
}
private void SetTargetPosition(Vector3 target)
{
targetPosition = target;
animator.SetBool("isWalking", true);
}
}
NPCMovement이라는 스크립트를 만들고 해당 오브젝트에 할당시켜, 오브젝트의 생성과 이동을 설정했다.
private void SpawnNPC()
{
foreach (var npcObject in npcObjects)
{
if (!npcObject.activeInHierarchy)
if (!npcObject.activeInHierarchy)
{
NPCMovement npcMovement = npcObject.GetComponent<NPCMovement>();
npcMovement.SetStartPosition();
NPC npcComponent = npcObject.GetComponent<NPC>();
NPCImageController npcImageController = npcObject.GetComponent<NPCImageController>();
Animator npcAnimator = npcObject.GetComponent<Animator>();
NPCData selectedNPCData = ChooseRandomNPCData();
ItemSO selectedItem = ChooseRandomItem();
if (npcComponent != null && npcImageController != null && selectedNPCData != null && selectedItem != null)
{
npcComponent.NPCInit(selectedNPCData, selectedItem);
npcImageController.Initialize(selectedNPCData.npcID, selectedItem.itemID);
AnimatorOverrideController overrideController = new AnimatorOverrideController(npcAnimator.runtimeAnimatorController);
overrideController["Base Layer.Idle"] = selectedNPCData.idleAnimation;
overrideController["Base Layer.Walk"] = selectedNPCData.walkAnimation;
npcAnimator.runtimeAnimatorController = overrideController;
}
npcObject.SetActive(true);
spawnedNPCsCount++;
}
}
}
NPCSpawner이라는 NPC 생성을 담당하는 스크립트에서 해당 내용을 참조했다.
public void OnClickRestButton()
{
SoundManager.Instance.SfxPlay(Enums.SFX.Button);
if (npcSpawner != null)
{
foreach (var npcObject in npcSpawner.npcObjects)
{
NPCMovement npcMovement = npcObject.GetComponent<NPCMovement>();
if (npcMovement != null)
{
npcMovement.TurnAround();
npcMovement.WalkOutOfScreen();
}
}
npcSpawner.ResetDay();
}
NPC가 생성되는 것 뿐 아니라 의뢰를 완료하고 돌아가는 시점에도 뒤돌아서 잘 돌아가도록 BedUI(하루를 마무리하는 버튼)에서 해당 내용을 참조했다.