유니티 플라잉보드, 호버보드 시스템
- hbController.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HbController : MonoBehaviour
{
Rigidbody rb;
// 부력 계산에 사용할 멀티플라이어
public float multiplier;
// 전진할 때 사용할 힘과 회전할 때 사용할 토크 값
public float moveForce, turnTorque;
// 호버보드를 지탱하는 앵커들 (4개의 Transform 위치)
public Transform[] anchors = new Transform[4];
// RaycastHit 배열로, 앵커 각각에 대한 바닥 충돌 정보를 저장
RaycastHit[] hits = new RaycastHit[4];
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
// 현재는 Update에 별다른 로직이 없지만, 입력 등을 여기에 추가할 수 있음
}
// FixedUpdate는 매 물리 프레임마다 호출되며, 물리적인 계산을 처리함
private void FixedUpdate()
{
// 4개의 앵커 각각에 대해 물리적인 부력을 적용
for (int i = 0; i < 4; i++)
{
// 앵커와 해당 앵커의 RaycastHit 정보를 전달하여 부력을 계산
ApplyForce(anchors[i], hits[i], i);
}
// 사용자의 입력을 받아 전방으로 움직이는 힘을 적용 (W, S키 등)
rb.AddForce(Input.GetAxis("Vertical") * moveForce * transform.forward);
// 사용자의 입력을 받아 좌우 회전 토크를 적용 (A, D키 등)
rb.AddTorque(Input.GetAxis("Horizontal") * turnTorque * transform.up);
//rb.AddForce(Input.GetAxis("Horizontal") * turnTorque * transform.up);
}
// 앵커 위치를 기준으로 바닥에 Ray를 쏘아 부력을 적용하는 함수
void ApplyForce(Transform anchor, RaycastHit hit, int index)
{
// 앵커의 위치에서 바닥으로 Ray를 쏴서 바닥과 충돌했는지 확인
if (Physics.Raycast(anchor.position, -anchor.up, out hit))
{
// 충돌 정보를 hits 배열에 저장 (Raycast의 결과)
hits[index] = hit;
// 부력 계산을 위한 힘 변수 초기화
float force = 0;
// 앵커와 바닥 사이의 거리에 따라 부력을 계산 (거리가 짧을수록 더 큰 부력)
force = Mathf.Abs(1 / (hit.point.y - anchor.position.y));
// 계산된 부력을 해당 앵커 위치에 적용, 부유하는 힘을 생성
rb.AddForceAtPosition(transform.up * force * multiplier, anchor.position, ForceMode.Acceleration);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Rendering;
using UnityEditor.ShaderGraph;
using UnityEngine;
public class player_move : MonoBehaviour
{
CharacterController characterController;
PlayerControlls playerControlls;
[SerializeField] float runSpeed;
[SerializeField] float walkSpeed = 3f;
Vector3 movementDirection;
public Vector2 moveInput { get; private set; }
public float speed;
float verticalVelocity;
bool isRunning = false;
bool onHoverBoard = false;
private void Awake()
{
playerControlls = new PlayerControlls();
}
void Start()
{
characterController = GetComponent<CharacterController>();
speed = walkSpeed;
AssignInputEvents();
}
void Update()
{
GameObject hover = GameObject.FindWithTag("Hover");
if(onHoverBoard == false)
{
movementDirection = new Vector3(moveInput.x, 0, moveInput.y);
ApplyGravity();
if (movementDirection.magnitude > 0)
{
characterController.Move(movementDirection * speed * Time.deltaTime);
}
}
if (Input.GetKeyDown(KeyCode.E))
{
onHoverBoard = true;
}
if(onHoverBoard)
{
gameObject.transform.localPosition = hover.transform.localPosition;
gameObject.transform.localRotation = hover.transform.localRotation;
}
}
private void ApplyGravity()
{
if (characterController.isGrounded == false)
{
verticalVelocity -= 9.81f * Time.deltaTime;
movementDirection.y = verticalVelocity;
}
else
{
verticalVelocity = -0.5f;
}
}
private void AssignInputEvents()
{
playerControlls.Character.Movement.performed += context => moveInput = context.ReadValue<Vector2>();
playerControlls.Character.Movement.canceled += context => moveInput = Vector2.zero;
playerControlls.Character.Run.performed += context =>
{
speed = runSpeed;
isRunning = true;
};
playerControlls.Character.Run.canceled += context =>
{
speed = walkSpeed;
isRunning = false;
};
}
private void OnEnable()
{
if (playerControlls == null)
{
playerControlls = new PlayerControlls();
}
playerControlls.Enable();
}
private void OnDisable()
{
playerControlls.Disable();
}
}
추천 설정: 0 (또는 매우 낮은 값)
추천 설정: 0 ~ 0.2 (정지 시에도 부드럽게 유지하되, 완전히 미끄러지지 않게 설정)
추천 설정: Minimum (부드러운 움직임을 위해 작은 마찰력 선택)
호버보드는 충돌 후에 튕겨 오르는 느낌이 적어야 하므로, Bounciness 값은 낮게 설정해야 합니다.
호버 보드 시스템 - 보완중
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HoverboardController : MonoBehaviour
{
public float hoverHeight = 2.0f; // 호버 높이
public float hoverForce = 50.0f; // 부유 힘
public float moveSpeed = 10.0f; // 전진 속도
public float turnSpeed = 100.0f; // 회전 속도
public float strafeSpeed = 7.0f; // 좌우 이동 속도 (스트레이프)
public LayerMask groundLayer; // 바닥 감지용 레이어
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
rb.useGravity = true; // 중력 사용
}
void FixedUpdate()
{
Hover();
Move();
}
void Hover()
{
// 바닥에서부터의 거리 측정
Ray ray = new Ray(transform.position, Vector3.down);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, hoverHeight * 2, groundLayer))
{
// 목표 높이에서 얼마나 떨어졌는지 계산
float heightDifference = hoverHeight - hit.distance;
// 부유 힘 적용
Vector3 force = Vector3.up * heightDifference * hoverForce;
rb.AddForce(force, ForceMode.Acceleration);
}
}
void Move()
{
// 캐릭터처럼 움직임 처리
//float moveInput = Input.GetAxis("Vertical");
//float turnInput = Input.GetAxis("Horizontal");
// 즉각적인 전방 이동 및 회전
//transform.Translate(Vector3.forward * moveInput * moveSpeed * Time.deltaTime);
//transform.Rotate(Vector3.up * turnInput * turnSpeed * Time.deltaTime);
// 전방/후방 이동
float moveInput = Input.GetAxis("Vertical");
transform.Translate(Vector3.forward * moveInput * moveSpeed * Time.deltaTime);
// 좌우 스트레이프 이동 (스트레이프)
float strafeInput = Input.GetAxis("Horizontal");
transform.Translate(Vector3.right * strafeInput * strafeSpeed * Time.deltaTime);
// 좌우 회전 (회전은 별도의 입력으로 분리)
//float turnInput = Input.GetAxis("Horizontal");
//transform.Rotate(Vector3.up * turnInput * turnSpeed * Time.deltaTime);
}
}
--- 아래 코드가 원하는 방향에 가깝게 움직임.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HoverboardController : MonoBehaviour
{
public float hoverHeight = 2.0f; // 호버 높이
public float hoverForce = 50.0f; // 부유 힘
public float moveSpeed = 10.0f; // 전진 속도
public float strafeSpeed = 7.0f; // 좌우 이동 속도
public float turnSensitivity = 2.0f; // 마우스 회전 감도
public Transform cameraTransform; // 카메라 트랜스폼 참조
public LayerMask groundLayer; // 바닥 감지용 레이어
private Rigidbody rb;
private float rotationY = 0f;
void Start()
{
rb = GetComponent<Rigidbody>();
rb.useGravity = true; // 중력 사용
Cursor.lockState = CursorLockMode.Locked; // 마우스 잠금
}
void FixedUpdate()
{
Hover();
Move();
RotateWithMouse();
}
void Hover()
{
// 바닥에서부터의 거리 측정
Ray ray = new Ray(transform.position, Vector3.down);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, hoverHeight * 2, groundLayer))
{
// 목표 높이에서 얼마나 떨어졌는지 계산
float heightDifference = hoverHeight - hit.distance;
// 부유 힘 적용
Vector3 force = Vector3.up * heightDifference * hoverForce;
rb.AddForce(force, ForceMode.Acceleration);
}
}
void Move()
{
// 전후/좌우 이동 (카메라 기준 방향)
float moveInput = Input.GetAxis("Vertical");
float strafeInput = Input.GetAxis("Horizontal");
// 카메라 방향을 기준으로 이동 벡터 계산
Vector3 forward = cameraTransform.forward;
Vector3 right = cameraTransform.right;
// 수직축은 무시하여 평면에서만 움직이도록 처리
forward.y = 0f;
right.y = 0f;
forward.Normalize();
right.Normalize();
// 전후/좌우 이동
Vector3 moveDirection = (forward * moveInput + right * strafeInput).normalized;
rb.MovePosition(rb.position + moveDirection * moveSpeed * Time.deltaTime);
}
void RotateWithMouse()
{
// 마우스 X 입력을 사용하여 회전
float mouseX = Input.GetAxis("Mouse X") * turnSensitivity;
rotationY += mouseX;
// Y축 회전 적용
transform.rotation = Quaternion.Euler(0, rotationY, 0);
}
}
유니티 딕셔너리 (0) | 2024.11.01 |
---|---|
유니티 뉴인풋시스템 - 구르기, 회피, 닷지, 롤 (0) | 2024.10.24 |
유니티 뉴 인풋 시스템 무기 교체, 드랍(버리기), 픽업(획득) (0) | 2024.10.15 |
유니티 포스트프로세싱 블룸 (0) | 2024.10.15 |
유니티 오브젝트에 레이어 이름 추가하기(스크립트로 추가) (0) | 2024.10.15 |