2021. 4. 14. 12:19ㆍunity
글로벌 일루미네이션 (GI)
물체의 표면에 직접 들어오는 빛뿐만 아니라
다른 물체의 표면에 반사되어 들어온 간접광까지 표현하는 것
angluar drag 회전할 때의 마찰력
apply root motion
게임 오브젝트의 위치와 모션을 애니메이션이 제어하도록 한다.
cinemachine
deadzone (중앙)
soft zone (파랑)
hard limit (빨강)
dead zone: 주시하는 물체가 게임 화면 밖으로 벗어나지 않게 추적의 세기를 단계별로 설정
카메라가 주시하는 물체가 화면의 데드존에 있는 동안 카메라가 회전하지 않는다.
soft zone: 주시하는 물체가 화면의 소프트존에 있다면 물체가 화면의 조준점에 오도록 카메라가 부드럽게 회전한다.
hard limit: 만약 물체가 너무 빠르게 움직여 화면의 소프트존을 벗어나 하드 리밋에 도달하려 한다면 카메라가 격하게 회전한다.
카메라가 주시하는 물체는 화면의 소프트존을 벗어나지 않는다.
데드존과 소프트존의 크기를 줄이면 물체가 조금이라도 화면 중앙을 벗어나러 할 때
지연 시간 없이 카메라가 즉시 물체를 향해 회전, 화면의 움직임이 딱딱하게 느껴질 수도 있다.
반대로 데드존과 소프트존의 크기를 늘리면 물체를 좇는 화면의 움직임이 느리게 느껴질 수 있다.
damping: 카메라의 회전 속도 결정 (수치가 높을 수록 격하게 움직임)
Coroutine
docs.unity3d.com/kr/530/Manual/Coroutines.html
실행을 중지하여 Unity에 제어권을 돌려주고, 그러나 계속할 때는 다음 프레임에서 중지한 곳부터 실행을 계속할 수 있는 기능
코루틴을 실행하려면 StartCoroutine 함수를 사용합니다.
Fade 함수의 루프 카운터는 코루틴의 라이프 사이클을 통해 올바른 값을 유지합니다.
yield 중에 모든 변수 또는 파라미터가 올바르게 보존됩니다.
기본적으로 코루틴은 yield 한 직후의 프레임에서 재개되지만, 지연했다가
다시 시작하려면 WaitForSeconds 함수를 사용합니다.
이 방법으로 효과를 일정한 시간 범위에서 펼칠 수 있지만, 최적화 방법으로 해도 편리합니다.
IEnumerator Fade() {
for (float f = 1f; f >= 0; f -= 0.1f) {
Color c = renderer.material.color;
c.a = f;
renderer.material.color = c;
yield return new WaitForSeconds(.1f);
}
}
작업이 너무 자주 반복할 필요가 없는 경우, 코루틴에 넣어 매 프레임 실행하지 않고 정기적으로 업데이트 할 수 있습니다.
예를 들자면, 적이 근처에 있는 것을 플레이어에게 알리는 알람입니다.
적이 많은 경우에 이 함수를 매 프레임 호출하여 현저한 오버 헤드를 초래할 지도 모릅니다. 그러나 코루틴을 사용하여 1/10 초 간격으로 호출할 수 있습니다
Coroutine 변수로 받아서
StopCoroutine(변수)로 코루틴 멈춤 가능
using UnityEngine;
using UnityEngine.AI;
public class App : MonoBehaviour
{
public Transform point;
public NavMeshAgent agent;
public Zombie zombie;
// Start is called before the first frame update
void Start()
{
this.zombie.Init();
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
//마우스 버튼 누른 쪽으로 raycast 생성
var ray=Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 1000f))
{
Debug.DrawRay(ray.origin, ray.direction * 1000f, Color.red, 1f);
NavMeshHit navHit;
this.point.transform.position = hit.point;
//해당 포지션이 네브메쉬 위에 있는가?
var result=NavMesh.SamplePosition(hit.point, out navHit, 1f, NavMesh.AllAreas);
Debug.Log(result);
if (result)
{
agent.isStopped = false;
agent.SetDestination(hit.point);
}
};
}
}
}
using UnityEngine;
public class Zombie : MonoBehaviour
{
public float radius= 2.0f;
public void Init()
{
this.StartCoroutine(this.DetectTarget());
}
private IEnumerator DetectTarget()
{
while (true)
{
Debug.Log("detect");
yield return new WaitForSeconds(1f);
}
}
private void OnDrawGizmos()
{
Gizmos.color = Color.yellow;
Gizmos.DrawSphere(this.transform.position,2);
}
}
캐릭터와 총에게 IK적용
using UnityEngine;
public class PlayerShooter : MonoBehaviour
{
private GameObject gun;
private Transform gunPivot;
public Transform leftHandMount;
public Transform rightHandMount;
public Animator playerAnim;
private GameObject player;
// Start is called before the first frame update
void Start()
{
player = GetComponent<GameObject>();
gun = GetComponent<GameObject>();
playerAnim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
}
//애니메이터의 IK 갱신
private void OnAnimatorIK(int layerIndex)
{
//IK를 사용하여 왼손의 위치와 회전을 총의 왼쪽 손잡이에
playerAnim.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1f);
playerAnim.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1f);
playerAnim.SetIKPosition(AvatarIKGoal.LeftHand, leftHandMount.position);
playerAnim.SetIKRotation(AvatarIKGoal.LeftHand, leftHandMount.rotation);
//IK를 사용하여 오른손의 위치와 회전을 총의 오른쪽 손잡이에
playerAnim.SetIKPositionWeight(AvatarIKGoal.RightHand, 1f);
playerAnim.SetIKRotationWeight(AvatarIKGoal.RightHand, 1f);
playerAnim.SetIKPosition(AvatarIKGoal.RightHand, rightHandMount.position);
playerAnim.SetIKRotation(AvatarIKGoal.RightHand, rightHandMount.rotation);
}
}
물체의 pivot은 캐릭터의 손과 되도록 가까운 위치에 맞춰야 하는 것 같다...
www.youtube.com/watch?v=7Xy7nRDdDHI&list=PL5kjuqWePlOoR6OJy8Ula_14FzMb9Zpnc&index=10
SetIKPositionWeight: IK 목표의 변환 가중치를 설정한다.
SetIKPositionWeight(AvatarIKGoal 목표, float 값)
IK 목표는 특정 신체 부위에 대한 대상 위치 및 회전
float는 IK가 조준 할 시작 위치와 목표 위치 사이의 거리
SetIKPosition:
public void SetIKPosition ( AvatarIKGoal goal , Vector3 goalPosition );
이 함수는 항상 MonoBehaviour.OnAnimatorIK 에서 호출되어야합니다 .
IK 목표는 특정 신체 부위에 대한 대상 위치 및 회전입니다.
AvatarIKGoal : IK 가중치, 위치 및 회전을 설정하고 가져온다.
AvatarIKGoal.Left/RightHand
'unity' 카테고리의 다른 글
0415 Line Renderer (0) | 2021.04.15 |
---|---|
0415 코루틴 사용해서 자동총쏘기 구현+코루틴 연습(fadeout) (0) | 2021.04.15 |
0412 쿠키런 달리기 (0) | 2021.04.12 |
0409 캐릭터의 시야각과 공격범위 생성 (0) | 2021.04.09 |
0409 총알 피하기 게임 (랜덤 총알 + 유도탄 생성) (0) | 2021.04.09 |