由於unity自帶的碰撞組件特別耗費性能,網上的unity物體碰撞的c#代碼實現比較少,沒有適合的,只能自己寫一個來用:
立方體:
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Assets
{
class Class1 : MonoBehaviour
{
List<Action> listAction = new List<Action>();
//用來檢測碰撞的間隔時間(可以直接把檢測放入update()中,不過100毫秒的定時器效果上也能實現)
System.Timers.Timer timer = new System.Timers.Timer();
//原坐標
Vector3 oldPoint;
//要移動的坐標
Vector3 point;
//0:待機;1:移動
int currentState = 0;
//是否可以移動
bool canMove = true;
// Use this for initialization
void Start()
{
oldPoint = transform.position;
timer.Interval = 100;
timer.Enabled = true;
timer.Elapsed += (a, b) => isMove(point);
}
// Update is called once per frame
void Update()
{
foreach (Action a in listAction) {
a();
}
listAction.Clear();
point = transform.position;
if (currentState == 1) {
if (checkCollision()) {
canMove = false;
}
}
}
void isMove(Vector3 position) {
if (oldPoint != position)
{
if (!canMove)
{
listAction.Add(new Action(()=> gameObject.transform.position = oldPoint));
canMove = true;
}
else {
currentState = 1;
oldPoint = position;
}
}
else {
currentState = 0;
}
}
bool checkCollision() {
Vector3 zzPoint = gameObject.transform.position;
Vector3 zzScale = gameObject.transform.localScale;
//另一物體坐標信息
GameObject dm = GameObject.Find("Cube (1)");
Vector3 dmPoint = dm.transform.position;
Vector3 dmScale = dm.transform.localScale;
//坐標檢測(當兩個物體的x、y、z方向間距都小於兩個物體在該方向上的長度)
if ((Math.Abs(zzPoint.x - dmPoint.x) <= zzScale.x / 2 + dmScale.x / 2) &&
(Math.Abs(zzPoint.y - dmPoint.y) <= zzScale.y / 2 + dmScale.y / 2) &&
(Math.Abs(zzPoint.z - dmPoint.z) <= zzScale.z / 2 + dmScale.z / 2))
{
return true;
}
return false;
}
}
}
球體:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class sphereCollision : MonoBehaviour {
List<Action> listAction = new List<Action>();
//用來檢測碰撞的間隔時間(可以直接把檢測放入update()中,不過100毫秒的定時器效果上也能實現)
System.Timers.Timer timer = new System.Timers.Timer();
//原坐標
Vector3 oldPoint;
//要移動的坐標
Vector3 point;
//0:待機;1:移動
int currentState = 0;
//是否可以移動
bool canMove = true;
// Use this for initialization
void Start()
{
oldPoint = transform.position;
timer.Interval = 100;
timer.Enabled = true;
timer.Elapsed += (a, b) => isMove(point);
}
// Update is called once per frame
void Update()
{
foreach (Action a in listAction)
{
a();
}
listAction.Clear();
point = transform.position;
if (currentState == 1)
{
if (sphereCheckCollision())
{
canMove = false;
}
}
}
void isMove(Vector3 position)
{
if (oldPoint != position)
{
if (!canMove)
{
listAction.Add(new Action(() => gameObject.transform.position = oldPoint));
canMove = true;
}
else
{
currentState = 1;
oldPoint = position;
}
}
else
{
currentState = 0;
}
}
bool sphereCheckCollision()
{
Vector3 zzPoint = gameObject.transform.position;
Vector3 zzScale = gameObject.transform.localScale;
//另一物體坐標信息
GameObject dm = GameObject.Find("Sphere (1)");
Vector3 dmPoint = dm.transform.position;
Vector3 dmScale = dm.transform.localScale;
//坐標檢測(當兩個圓相切時,圓心距離為r1+r2,兩個圓心在x、y、z上的距離差為x1、x2、x3,用三角函數計算時至少計算兩個維度的距離差才能和圓心距進行比較)
if ((Math.Sqrt(Math.Pow(Math.Abs(zzPoint.x - dmPoint.x), 2) + Math.Pow(Math.Abs(zzPoint.y - dmPoint.y), 2)) <= zzScale.x / 2 + dmScale.x / 2) &&
(Math.Sqrt(Math.Pow(Math.Abs(zzPoint.x - dmPoint.x), 2) + Math.Pow(Math.Abs(zzPoint.z - dmPoint.z), 2)) <= zzScale.x / 2 + dmScale.x / 2) &&
(Math.Sqrt(Math.Pow(Math.Abs(zzPoint.y - dmPoint.y), 2) + Math.Pow(Math.Abs(zzPoint.z - dmPoint.z), 2)) <= zzScale.x / 2 + dmScale.x / 2))
{
return true;
}
return false;
}
}