您的位置:首页 > 其它

带碰撞检测的摄像机

2015-09-24 20:36 393 查看
原文地址:http://blog.sina.com.cn/s/blog_4a2183a601018fmd.html

类似网游那样如果摄像机和目标之间有其他物体存在,就移动摄像机到障碍物前面

// CamController

// 带碰撞第三人称摄像机

//Edit by Shadou

//编写 傻逗

//

//create at 2011-8-4

//last change 2011-10-9

//

//Any bugs and suggestions please e-mail to 51149526@qq.com or visit my blog

//

//



@script AddComponentMenu ("SDTK/Camera/Thrid person Cam")

var target : Transform; //目标物体

var mask: LayerMask;//layer层 //只检测在mask 包含的层里的碰撞体是否会遮挡视线



var targetHeight = 2.0; //实际聚焦点位置处于目标坐标上方的高度值 //不宜过高,否则会影响视线检测的位置

var distance = 5.0;// 摄像机距离实际聚焦点的距离



var maxDistance = 20; //摄像机距离实际聚焦点的最大距离

var minDistance = 2.5; //摄像机距离实际聚焦点的最小距离



var xSpeed = 250.0; //横向移动速度(eulerAngles.y)

var ySpeed = 120.0; //纵向移动速度(eulerAngles.x)



var yMinLimit = -20; //摄像机仰角(eulerAngles.x)最小值

var yMaxLimit = 80; //摄像机仰角(eulerAngles.x)最大值



var zoomRate = 20; //推拉摄像机的速度



var rotationDampening = 2.0; //摄像机移动阻尼 //数值越小摄像机停止的速度越慢, 数值越高停止的速度越快



private var x = 0.0; //水平旋转角度

private var y = 0.0; //仰角旋转角度



private var xDampMove: float=0;//水平旋转阻尼速度

private var yDampMove: float=0;//仰角旋转阻尼速度



private var targetDistance: float=0;





function Awake () {

var angles = transform.eulerAngles;

x = angles.y;

y = angles.x;



// Make the rigid body not change rotation

//防止刚体影响物体旋转

if (rigidbody)

rigidbody.freezeRotation = true;



targetDistance=distance;

}



//摄像机位移应该在所有其他物体计算之后处理 //LateUpdate 晚于 Update

//防止摄像机移动后有其他物体移动道遮挡的位置, 或者与目标物体位移不同步

function LateUpdate () {

if(!target)

return;



// If either mouse buttons are down, let them govern camera position

//鼠标点击移动摄像机

if(Input.GetMouseButton(2) || Input.GetMouseButton(1)){

xDampMove=Input.GetAxis("Mouse X") * xSpeed;

yDampMove=Input.GetAxis("Mouse Y") * ySpeed;

}



// move cam using arrow keys

//使用键盘移动摄像机

//~xDampMove-=(xDampMove<xSpeed/2f)?(Input.GetAxis("Horizontal")*xSpeed*0.25f):0;

//~ yDampMove-=(xDampMove<xSpeed/2f)?(Input.GetAxis("Vertical")*ySpeed*0.25f):0;



//clamp speed

//限制移动速度最大值

xDampMove=Mathf.Clamp(xDampMove,-xSpeed,xSpeed);

yDampMove=Mathf.Clamp(yDampMove,-ySpeed,ySpeed);



//apply

//施加摄像机移动

x+=xDampMove*Time.deltaTime;

y-=yDampMove*Time.deltaTime;



//distance change

//更改摄像机与目标之间的距离

if(Input.GetKey("q"))

distance-=zoomRate*0.25f*Time.deltaTime;



if(Input.GetKey("e"))

distance+=zoomRate*0.25f*Time.deltaTime;



distance -= (Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime) * zoomRate * Mathf.Abs(distance);

distance = Mathf.Clamp(distance, minDistance, maxDistance);



//缩放施加阻尼

targetDistance=Mathf.Lerp(targetDistance,distance,2*Time.deltaTime);



//限制仰角

y = ClampAngle(y, yMinLimit, yMaxLimit);



//calcu

//计算摄像机的角度和方向

var rotation : Quaternion = Quaternion.Euler(y, x, 0);

var position : Vector3= rotation * Vector3.forward * -targetDistance + target.position+Vector3(0,targetHeight,0);



//slowDown

//对摄像机的移动施加阻尼

xDampMove=Mathf.Lerp(xDampMove,0,rotationDampening*Time.deltaTime);

yDampMove=Mathf.Lerp(yDampMove,0,rotationDampening*Time.deltaTime);





//checkLineOfSign and Collision

//检测是否有碰撞体遮挡视线

//如果有则移动摄像机的位置到障碍物前面

position=SignUpdate(target.position+Vector3.up*targetHeight,position,0.3f, distance,0.6f,mask);



//change distance if want

//更改摄像机位置的同时更改距离 如果需要

//开启时摄像机离开障碍物遮挡后不会突然跳跃

//

targetDistance=Vector3.Distance(position,target.position+Vector3.up*targetHeight);

//





//Apply

//施加摄像机位移和旋转

transform.rotation=rotation;

transform.position=position;



}



//限制角度

static function ClampAngle (angle : float, min : float, max : float) {

if (angle < -360)

angle += 360;

if (angle > 360)

angle -= 360;

return Mathf.Clamp (angle, min, max);

}



//检测是否有碰撞体遮挡在 targetPoint 和 selfPosition 之间

//targetPoint 目标位置

//selfPosition 自身位置

//checkRadios 球星检测区域半径

//maxDis 最大检测距离

//stepDis 检测倒碰撞后向前偏移的位置, 建议大于检测半径*2

//s_mask 碰撞检测遮罩

function SignUpdate(targetPoint: Vector3, selfPosition: Vector3, checkRadios: float, maxDis: float, stepDis: float, s_mask: LayerMask): Vector3{

var ray: Ray=new Ray(targetPoint,selfPosition-targetPoint);

var hit: RaycastHit;



if(Physics.SphereCast(ray,checkRadios,hit,maxDis,s_mask)){



return ray.GetPoint(hit.distance-stepDis);

}



//无碰撞返回原始位置

return selfPosition;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: