public static CameraTraceResult CameraTrace(int layerMask, Vector3 vCenter, float radius, Vector3 vDelta, out Vector3 vEndPos, out float fDistance) { CameraTraceResult result = CameraTraceResult.NoHit; RaycastHit hitInfo; float fMaxDistance = vDelta.magnitude; vDelta.Normalize(); if (Physics.SphereCast(vCenter, radius, vDelta, out hitInfo, fMaxDistance, layerMask)) { fDistance = hitInfo.distance; vEndPos = hitInfo.point; GameObject goHit = hitInfo.collider.gameObject; if (goHit != null) { if (goHit.layer == CUnityUtil.Layer_Terrain) { result = CameraTraceResult.HitTerrain; } else //if (goHit.layer == CUnityUtil.Layer_CameraCollision) { result = CameraTraceResult.HitCameraCollision; } } } else { fDistance = 0.0f; vEndPos = vCenter; } return(result); }
private void CamMoveNear(LuaFunction callback = null) { _CurStage = MoveStage.MOVING_NEAR; SetDegAndDistance(_Params.x, _Params.y, _Params.z, _Params.w); _CurTargetPos = GetRealLookPos(_HeightOffset); var dest_point = _CurTargetPos - _RealDir * _DistOffset; dest_point = GetCamPosAfterCollionFix(dest_point); _CameraTrans.DOMove(dest_point, CAMERA_IN_DURATION).SetEase(Ease.OutCirc).OnUpdate(() => { UpdateHostPlayerIsNeedHide(); _CameraTrans.LookAt(_CurTargetPos); }).OnComplete(() => { if (callback != null) { callback.Call(); callback.Release(); } _CurHeightOffset = _CurTargetPos.y - LookAtTarget.position.y; _RealPos = _CameraTrans.position; _CamTraceResult = CameraTraceResult.NoHit; _CurStage = MoveStage.LOOKING_AT; }); }
//相机遇遮挡时拉进的设置 private bool CollisionFix(int layerMask) { CameraTraceResult bLastCollide = _CamTraceResult; if (bLastCollide == CameraTraceResult.NoHit || _IsDistChange) { dist_before_hit = _DistOffset; _IsDistChange = false; } Vector3 vDelta = -dist_before_hit * _RealDir; bool isFix = false; Vector3 vTracePos; float fDistance; _CamTraceResult = CMapUtil.CameraTrace(layerMask, _CurTargetPos, 0.02f, vDelta, out vTracePos, out fDistance); if (_CamTraceResult == CameraTraceResult.HitTerrain) { if (fDistance > 0.1f) //避免出现摄像机位置和碰撞位置重合的情况,这时方向会乱 { _RealPos = vTracePos; } else { vDelta.Normalize(); _RealPos = _CurTargetPos + vDelta * 0.1f; } _DistOffsetDest = fDistance; isFix = true; } else if (_CamTraceResult == CameraTraceResult.HitCameraCollision) { if (fDistance > _MinCamCollisionDist) //避免出现摄像机位置和碰撞位置重合的情况,这时方向会乱 { _RealPos = vTracePos; } else { vDelta.Normalize(); _RealPos = _CurTargetPos + vDelta * _MinCamCollisionDist; } } else { if (bLastCollide != CameraTraceResult.NoHit) //从有碰撞到无碰撞 { _DistOffset = _DistOffsetDest = dist_before_hit; } } return(isFix); }
private bool CollisionFix(int layerMask) { bool bHideTarget = false; CameraTraceResult bLastCollide = _CamTraceResult; if (bLastCollide == CameraTraceResult.NoHit || _IsDistChangeByForce) { dist_before_hit = _DistOffset; _IsDistChangeByForce = false; } Vector3 vDelta = -dist_before_hit * _RealDir; Vector3 vTracePos; float fDistance; _CamTraceResult = CMapUtil.CameraTrace(layerMask, _CurLookAtPos, _CameraRadius, vDelta, out vTracePos, out fDistance); if (_CamTraceResult == CameraTraceResult.HitTerrain) { _IsQuickRecoverDist = false; _DistOffset = _DistOffsetDest; float dist = fDistance; if (fDistance <= 0.1f) //避免出现摄像机位置和碰撞位置重合的情况,这时方向会乱 { dist = 0.1f; } //_CurHeightOffset = GetHeightOffsetByDistOffset(dist); //real_look_at_pos = GetRealLookPos(_CurHeightOffset); vDelta.Normalize(); _RealPos = _CurLookAtPos + vDelta * dist; } else if (_CamTraceResult == CameraTraceResult.HitCameraCollision) { _IsQuickRecoverDist = false; _DistOffset = _DistOffsetDest; float dist = fDistance; if (fDistance <= _MinCamCollisionDist) { dist = _MinCamCollisionDist; } vDelta.Normalize(); _RealPos = _CurLookAtPos + vDelta * dist; } else { if (bLastCollide != CameraTraceResult.NoHit) { _DistOffset = Mathf.Clamp(dist_before_hit, CamConfig.CamMinOffsetDist, _CurMaxDistOffset); //_DistOffset = (_CurLookAtPos - _RealPos).magnitude; //_DistOffset = Mathf.Clamp(_DistOffset, CamConfig._CamMinOffsetDist, _CurMaxDistOffset); _IsQuickRecoverDist = true; } _RealPos = _CurLookAtPos - _DistOffset * _RealDir; } bool bTerrainFix = false; float fTargetHeight; if (!CMapUtil.GetMapHeight(_CurLookAtPos, _CameraRadius, out fTargetHeight)) { fTargetHeight = CUnityUtil.InvalidHeight; } //确保在地面一定高度 float fHeight = 0.0f; if (CMapUtil.GetMapHeight(_RealPos, _CameraRadius, out fHeight)) { Vector3 vPos = _RealPos; if (vPos.y < fHeight + _CameraTerrainHitHeight) { vPos.y = fHeight + _CameraTerrainHitHeight; if ((vPos - _CurLookAtPos).sqrMagnitude < _DistOffset * _DistOffset) { _RealPos = vPos; bTerrainFix = true; } //_DistOffset = (_CurLookAtPos - _RealPos).magnitude; } //不能低于目标所在的高度 if (fTargetHeight != CUnityUtil.InvalidHeight && vPos.y < fTargetHeight + _CameraTerrainHitHeight) { vPos.y = fTargetHeight + _CameraTerrainHitHeight; _RealPos = vPos; bTerrainFix = true; } } if (!bTerrainFix) { bHideTarget = (_RealPos - _CurLookAtPos).sqrMagnitude < _MinCamHostDist * _MinCamHostDist; } return(bHideTarget); }