最近接了能动学院的项目做一个水电系统油系统3D教学系统。其中要做一个类似地图模型展示的功能,第一版效果如下
map第一版演示
摄像机控制的代码如下
//这个是摄像机控制器基类
public class OriginCamera{
public Transform target;
public Camera cam;
public InputInfo info;
public ECameraState state;
public Action updateEvent;
public float maxOffset;
public float minOffset;
public EImportantAssembly eTarget=EImportantAssembly.None;
protected float offset;
protected float moveLerpSpeed=30f;
public OriginCamera(){
}
//摄像机初始化
public virtual void CameraInit(Transform target,Camera cam,InputInfo info){
this.target=target;
this.cam=cam;
this.info=info;
state=ECameraState.Switching;
updateEvent=OnSwitchingTarget;
maxOffset=50f;
minOffset=10f;
offset=maxOffset;
}
//摄像机update
public virtual void CameraUpdate(){
if (target == null)
{
return;
}
}
//当摄像机过渡到另一个目标
public virtual void OnSwitchingTarget(){
Vector3 curPos = cam.transform.position;
Vector3 targetPos = target.position;
Quaternion curRotation = cam.transform.rotation;
Vector3 cTor = targetPos - curPos;
if(Vector3.Angle(cTor,cam.transform.forward)>1f){
cam.transform.rotation= Quaternion.Lerp(curRotation,
Quaternion.LookRotation(cTor),
180/Quaternion.Angle(Quaternion.LookRotation(cTor),curRotation)*Time.deltaTime);
}
float distance = Vector3.Distance(curPos, targetPos);
if(distance>maxOffset){
cam.transform.position=Vector3.Lerp(curPos,targetPos,
moveLerpSpeed*Time.deltaTime/Vector3.Distance(curPos,targetPos));
}
else if (distance<minOffset)
{
cam.transform.position=Vector3.Lerp(curPos,targetPos-cTor.normalized*maxOffset,
moveLerpSpeed*Time.deltaTime/Vector3.Distance(curPos,targetPos-cTor.normalized*maxOffset));
}
else
{
if(Vector3.Angle(targetPos-curPos,cam.transform.forward)<1f){
offset=Vector3.Distance(curPos,targetPos);
state=ECameraState.Working;
updateEvent=CameraUpdate;
}
}
}
//当摄像机切换目标
public virtual void ChangeTarget(Transform target){
this.target=target;
state=ECameraState.Switching;
updateEvent=OnSwitchingTarget;
}
}
下面是UICamera控制脚本,写得效果不太好,需要重构代码逻辑
//这个是UICamera的脚本,继承自摄像机基类
public class ShowModelCamera:OriginCamera
{
public float sensibility;
public float scrollSpeed;
private Vector3 rotation;
private float angle;
private bool isUpdate=true;
public ShowModelCamera():base(){
}
public override void CameraInit(Transform target, Camera cam, InputInfo info)
{
base.CameraInit(target, cam, info);
sensibility=200f;
scrollSpeed=2500;
}
public override void CameraUpdate()
{
base.CameraUpdate();
SignUpdate();
if(isUpdate){
offset+=-info.scrollWheel*scrollSpeed*Time.deltaTime;
offset=Mathf.Clamp(offset,minOffset,maxOffset);
rotation.y = -info.mouseX * sensibility * Time.deltaTime;
target.Rotate(rotation);
}
}
public void SignUpdate(){
if(info.mouseLDown&&info.objOnClick!=null&&info.objOnClick.CompareTag("BackGroundUI")){
Cursor.lockState=CursorLockMode.Locked;
isUpdate=true;
}
else{
Cursor.lockState=CursorLockMode.None;
isUpdate=false;
}
}
public override void OnSwitchingTarget()
{
state=ECameraState.Working;
updateEvent=CameraUpdate;
}
}
可以看出来效果比较僵硬用户,用起来不知道哪是哪,对零部件模型所在位置也没有清楚的意识。
所以我决定优化其模型展示功能和按钮的交互性,添加过渡动画使其有更好的模型展示效果,预计在这周内更新优化后的效果和重构后的代码逻辑。