Unity中的自製重力,以下是程式碼:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyKinematic : MonoBehaviour {
public float gravity = 9.8f;//重力
public Vector3 velocity = Vector3.zero;//速率
public Vector3 deltaMove = Vector3.zero;//每偵位移量
public float halfBoundHeight;//物體的一半高度
public BoxCollider myCollider;//物體的Collider
public Vector3 addForce = Vector3.zero;//跳躍施力
// Use this for initialization
void Start ()
{
myCollider = GetComponent<BoxCollider>();
halfBoundHeight = (myCollider.size.y * 0.5f) * transform.localScale.y;
}
// Update is called once per frame
void Update ()
{
HandleKeyInput();//按鍵輸入函式
}
void LateUpdate()
{
float deltatime = Time.deltaTime;
UpdateGravity(deltatime);//重力
UpdateMovement(deltatime);//落下
}
void UpdateGravity(float deltatime)
{
velocity.y -= gravity * deltatime; ;
}
void UpdateMovement(float deltatime)
{
//落下
deltaMove = velocity * Time.deltaTime;
//碰撞判定
Vector3 raystart = transform.position + myCollider.center * transform.localScale.y;//射線起點
float updown = 1;//方向判定
if (velocity.y < 0)
updown = -1;
Vector3 raydir = Vector3.up * updown;
float rayLength = Mathf.Abs(deltaMove.y) + halfBoundHeight;
RaycastHit rhf = new RaycastHit();//射線
if (Physics.Raycast(raystart, raydir, out rhf, rayLength))
{
if (rhf.collider != null && rhf.collider.gameObject.tag == "ground")//地板判定
{
deltaMove.y = rhf.point.y - raystart.y + halfBoundHeight * -updown;
velocity = deltaMove / deltatime;
}
}
transform.Translate(deltaMove, Space.World);//物體移動
}
void AddForce(Vector3 force)
{
velocity += force;
}
void HandleKeyInput()
{
if (Input.GetKeyDown(KeyCode.W))
AddForce(addForce);
}
}
至於重力為什麼要重新製作,一方面是為了對整套重力系統重新做理解,另一方面則是Unity物理擬真程度的問題,有些時候其實不需要那麼真實的物理效果,而自製的物理可以簡化掉一些不需要的結果。
以下是參考的網站:
設計我們的遊戲物理-簡易重力篇