Vector3 GetLookTargetPosForSocialTriangle( FaceLookTarget playerFaceLookTarget ) { if ( currentTargetLeftEyeXform == null || currentTargetRightEyeXform == null ) return currentEyeTargetPOI.position; Vector3 faceTargetPos = Vector3.zero; Vector3 eyeCenter = 0.5f * (currentTargetLeftEyeXform.position + currentTargetRightEyeXform.position); switch( playerFaceLookTarget ) { case FaceLookTarget.EyesCenter: faceTargetPos = GetCurrentEyeTargetPos(); break; case FaceLookTarget.LeftEye: faceTargetPos = Vector3.Lerp(eyeCenter, currentTargetLeftEyeXform.position, 0.75f); break; case FaceLookTarget.RightEye: faceTargetPos = Vector3.Lerp(eyeCenter, currentTargetRightEyeXform.position, 0.75f); break; case FaceLookTarget.Mouth: Vector3 eyeUp = 0.5f * (currentTargetLeftEyeXform.up + currentTargetRightEyeXform.up); faceTargetPos = eyeCenter - eyeUp * 0.4f * Vector3.Distance( currentTargetLeftEyeXform.position, currentTargetRightEyeXform.position ); break; } return faceTargetPos; }
public void LookAtFace( Transform leftEyeXform, Transform rightEyeXform, float headLatency=0.075f ) { lookTarget = LookTarget.Face; headSpeed = HeadSpeed.Fast; faceLookTarget = FaceLookTarget.EyesCenter; this.headLatency = headLatency; currentTargetLeftEyeXform = leftEyeXform; currentTargetRightEyeXform = rightEyeXform; nextTargetLeftEyeXform = nextTargetRightEyeXform = null; nextHeadTargetPOI = null; StartEyeMovement( ); }
void CheckMacroSaccades() { if ( lookTarget == LookTarget.SpecificThing ) return; if ( controlData.eyeControl == ControlData.EyeControl.None ) return; if ( eyeLatency > 0 ) return; timeToMacroSaccade -= Time.deltaTime; if ( timeToMacroSaccade <= 0 ) { if ( lookTarget == LookTarget.GeneralDirection && useMacroSaccades) { const float kMacroSaccadeAngle = 10; bool hasBoneEyelidControl = controlData.eyelidControl == ControlData.EyelidControl.Bones; float angleVert = Random.Range(-kMacroSaccadeAngle * (hasBoneEyelidControl ? 0.65f : 0.3f), kMacroSaccadeAngle * (hasBoneEyelidControl ? 0.65f : 0.4f)); float angleHoriz = Random.Range(-kMacroSaccadeAngle,kMacroSaccadeAngle); SetMacroSaccadeTarget( eyesRootXform.TransformPoint( Quaternion.Euler( angleVert, angleHoriz, 0) * eyesRootXform.InverseTransformPoint( GetCurrentEyeTargetPos() ))); timeToMacroSaccade = Random.Range(5.0f, 8.0f); timeToMacroSaccade *= 1.0f/(1.0f + nervousness); } else if ( lookTarget == LookTarget.Face ) { if ( currentEyeTargetPOI == null ) { //*** Social triangle: saccade between eyes and mouth (or chest, if actor isn't looking back) { switch( faceLookTarget ) { case FaceLookTarget.LeftEye: faceLookTarget = Random.value < 0.75f ? FaceLookTarget.RightEye : FaceLookTarget.Mouth; break; case FaceLookTarget.RightEye: faceLookTarget = Random.value < 0.75f ? FaceLookTarget.LeftEye : FaceLookTarget.Mouth; break; case FaceLookTarget.Mouth: case FaceLookTarget.EyesCenter: faceLookTarget = Random.value < 0.5f ? FaceLookTarget.LeftEye : FaceLookTarget.RightEye; break; } SetMacroSaccadeTarget( GetLookTargetPosForSocialTriangle( faceLookTarget ) ); timeToMacroSaccade = (faceLookTarget == FaceLookTarget.Mouth) ? Random.Range(0.4f, 0.9f) : Random.Range(1.0f, 3.0f); timeToMacroSaccade *= 1.0f/(1.0f + nervousness); } } } } }