public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { Rect springPowerRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight); Rect springDamperRect = new Rect(position.x, springPowerRect.yMax + EditorGUIUtility.standardVerticalSpacing, position.width, EditorGUIUtility.singleLineHeight); Rect remainingRect = new Rect(position.x, springDamperRect.yMax + EditorGUIUtility.standardVerticalSpacing, position.width, position.yMax - springDamperRect.yMax); SerializedProperty springPowerProperty = property.FindPropertyRelative("Power"); SerializedProperty springDamperProperty = property.FindPropertyRelative("Damper"); EditorGUI.PropertyField(springPowerRect, springPowerProperty); EditorGUI.PropertyField(springDamperRect, springDamperProperty); if (Event.current.type == EventType.Repaint) { //EditorStyles.helpBox.Draw(remainingRect, GUIContent.none, 0); EditorGUI.DrawRect(remainingRect, new Color(0.1f, 0.1f, 0.1f, 1.0f)); List <float> cache = new List <float>(); Spring spring = new Spring(); spring.Power = springPowerProperty.floatValue; spring.Damper = springDamperProperty.floatValue; for (int i = 0; i < samples; i++) { cache.Add(spring.Value); spring.Update(1.0f / 60.0f); } Handles.BeginGUI(); Vector3[] graphInfo = new Vector3[cache.Count]; for (int i = 0; i < cache.Count; i++) { float time = ((float)i) / (cache.Count - 1); float value = cache[i]; graphInfo[i] = new Vector3(Mathf.Lerp(remainingRect.xMin, remainingRect.xMax, time), Mathf.Lerp(remainingRect.yMax, remainingRect.yMin, value), 0); if (i != 0) { Handles.DrawLine(graphInfo[i - 1], graphInfo[i]); } } Handles.color = Color.green; Handles.DrawPolyLine(graphInfo); Handles.EndGUI(); } }
void Update() { if (Input.GetKeyDown(KeyCode.X)) { spring.Velocity += bounceForce; } spring.Update(Time.deltaTime); Fader.alpha = spring.Value; Fader.transform.localScale = Vector3.one + (Vector3.one * Scaler * (1.0f - Mathf.Clamp01(spring.Value))); }
void DrawRope() { //If not grappling, don't draw rope if (!hook.init) { //currentGrapplePosition = grapplingGun.gunTip.position; currentGrapplePosition = transform.position; spring.Reset(); if (lr.positionCount > 0) { lr.positionCount = 0; } return; } if (lr.positionCount == 0) { spring.SetVelocity(velocity); lr.positionCount = quality + 1; } spring.SetDamper(damper); spring.SetStrength(strength); spring.Update(Time.deltaTime); var grapplePoint = hook.TagPos; //var grapplePoint = transform.position; var gunTipPosition = hook.grapple.ShootTransform.position; var up = Quaternion.LookRotation((grapplePoint - gunTipPosition).normalized) * Vector3.up; currentGrapplePosition = Vector3.Lerp(currentGrapplePosition, grapplePoint, Time.deltaTime * simualtionSpeed); for (var i = 0; i < quality + 1; i++) { var delta = i / (float)quality; var offset = up * waveHeight * Mathf.Sin(delta * waveCount * Mathf.PI) * spring.Value * affectCurve.Evaluate(delta); offset = new Vector3 ( Mathf.Clamp(offset.x, -waveHeight, waveHeight), Mathf.Clamp(offset.y, -waveHeight, waveHeight), Mathf.Clamp(offset.z, -waveHeight, waveHeight) ); lr.SetPosition(i, Vector3.Lerp(gunTipPosition, currentGrapplePosition, delta) + offset); } transform.position = lr.GetPosition(quality); }
public override void Simulate(Vector3 playerPosition, Vector3 playerAngles, float deltaTime) { var transform = this.transform; float interpolationDeltaTime = deltaTime * interpolationSpeed; _pitch.Update(interpolationDeltaTime); _yaw.Update(interpolationDeltaTime); _roll.Update(interpolationDeltaTime); _pitch.time = 0f; _yaw.time = 0f; _roll.time = 0f; var position = playerPosition; var angles = playerAngles; // spring position = _spring.Update( deltaTime * interpolationSpeed, position, springMass, springDampening, springCoefficients); // craning float ax = Angles.ToRelative(pitch); float ay = Mathf.DeltaAngle(angles.y, yaw); float dy = 1f - Mathf.Cos(ax * Mathf.Deg2Rad); float dz = 0f - Mathf.Sin(ax * Mathf.Deg2Rad); float ex = 0f - Mathf.Sin(ay * Mathf.Deg2Rad); float ez = 1f - Mathf.Cos(ay * Mathf.Deg2Rad); ex *= 1f - Mathf.Max(dz + 0.5f, 0f); ez *= 1f - Mathf.Max(dz + 0.5f, 0f); ex *= Mathf.Lerp(0.15f, 0.30f, Mathf.Abs(dz)); ez *= Mathf.Lerp(0.15f, 0.25f, Mathf.Abs(dz)); dy *= 0.05f; dz *= 0.35f; position.y += eyeHeight; position -= Quaternion.Euler(angles) * (new Vector3(0f, dy, dz) + new Vector3(ex, 0f, ez)); transform.localPosition = position; transform.localRotation = Quaternion.Euler(pitch, yaw, roll); }
void DrawRope() { //If not grappling, don't draw rope if (!grapplingGun.IsGrappling()) { currentGrapplePosition = grapplingGun.gunTip.position; spring.Reset(); if (lr.positionCount > 0) { lr.positionCount = 0; } return; } if (lr.positionCount == 0) { spring.SetVelocity(velocity); lr.positionCount = quality + 1; } spring.SetDamper(damper); spring.SetStrength(strength); spring.Update(Time.deltaTime); var grapplePoint = grapplingGun.GetGrapplePoint(); var gunTipPosition = grapplingGun.gunTip.position; var up = Quaternion.LookRotation((grapplePoint - gunTipPosition).normalized) * Vector3.up; currentGrapplePosition = Vector3.Lerp(currentGrapplePosition, grapplePoint, Time.deltaTime * 12f); for (var i = 0; i < quality + 1; i++) { var delta = i / (float)quality; var offset = up * waveHeight * Mathf.Sin(delta * waveCount * Mathf.PI) * spring.Value * affectCurve.Evaluate(delta); lr.SetPosition(i, Vector3.Lerp(gunTipPosition, currentGrapplePosition, delta) + offset); } }
public void UpdateStationaryTurret() { if (ShouldSleep()) { lightObject.shadows = LightShadows.None; if (audiosource_motor.isPlaying) { audiosource_motor.Stop(); } return; } else { if (!audiosource_motor.isPlaying) { audiosource_motor.volume = Preferences.sound_volume; audiosource_motor.Play(); } audiosource_motor.volume = 0.4f * Preferences.sound_volume; if (lightObject.intensity > 0.0f) { lightObject.shadows = LightShadows.Hard; } else { lightObject.shadows = LightShadows.None; } } Vector3 rel_pos = Vector3.zero; if (motor_alive) { switch (ai_state) { case AIState.IDLE: if (!LimitedRotation) { rotation_y.target_state += Time.deltaTime * 100.0f; } else { if (!Waiting) { rotation_y.target_state += Time.deltaTime * 100.0f * (FlipRotate ? -1f : 1f); } else { WaitTime += Time.deltaTime; if (WaitTime > EndWaitTime) { Waiting = false; WaitTime = 0f; } } if (Mathf.Abs(rotation_y.target_state) > RotationRange) { FlipRotate = !FlipRotate; Waiting = true; } rotation_y.target_state = Mathf.Clamp(rotation_y.target_state, -RotationRange, RotationRange); } break; case AIState.AIMING: case AIState.ALERT: case AIState.ALERT_COOLDOWN: case AIState.FIRING: rel_pos = target_pos - point_pivot.position; Vector3 x_axis = point_pivot.rotation * new Vector3(1.0f, 0.0f, 0.0f); Vector3 y_axis = point_pivot.rotation * new Vector3(0.0f, 1.0f, 0.0f); Vector3 z_axis = point_pivot.rotation * new Vector3(0.0f, 0.0f, 1.0f); Vector3 y_plane_pos = (new Vector3(Vector3.Dot(rel_pos, z_axis), 0.0f, -Vector3.Dot(rel_pos, x_axis))).normalized; float target_y = Mathf.Atan2(y_plane_pos.x, y_plane_pos.z) / Mathf.PI * 180 - 90; while (target_y > rotation_y.state + 180) { rotation_y.state += 360.0f; } while (target_y < rotation_y.state - 180) { rotation_y.state -= 360.0f; } rotation_y.target_state = target_y; float y_height = Vector3.Dot(y_axis, rel_pos.normalized); float target_x = -Mathf.Asin(y_height) / Mathf.PI * 180; rotation_x.target_state = target_x; rotation_x.target_state = Mathf.Min(40.0f, Mathf.Max(-40.0f, target_x)); break; } } if (battery_alive) { switch (ai_state) { case AIState.FIRING: trigger_down = true; break; default: trigger_down = false; break; } } if (barrel_alive) { if (trigger_down) { if (gun_delay <= 0.0f) { gun_delay += 0.1f; Instantiate(muzzle_flash, point_muzzle_flash.position, point_muzzle_flash.rotation); PlaySoundFromGroup(sound_gunshot, 1.0f); GameObject bullet = (GameObject)Instantiate(bullet_obj, point_muzzle_flash.position, point_muzzle_flash.rotation); bullet.GetComponent <BulletScript>().SetVelocity(point_muzzle_flash.forward * 300.0f); bullet.GetComponent <BulletScript>().SetHostile(); rotation_x.vel += (float)UnityEngine.Random.Range(-50, 50); rotation_y.vel += (float)UnityEngine.Random.Range(-50, 50); --bullets; } } if (ammo_alive && bullets > 0) { gun_delay = Mathf.Max(0.0f, gun_delay - Time.deltaTime); } } // Target interactions Transform target = GetTarget(); if (target != null) { float danger = 0.0f; float dist = Vector3.Distance(target.position + targetoffsetpos, transform.position); if (battery_alive) { danger += Mathf.Max(0.0f, 1.0f - dist / kMaxRange); } if (camera_alive) { if (danger > 0.0f) { danger = Mathf.Min(0.2f, danger); } if (ai_state == AIState.AIMING || ai_state == AIState.FIRING) { danger = 1.0f; } if (ai_state == AIState.ALERT || ai_state == AIState.ALERT_COOLDOWN) { danger += 0.5f; } rel_pos = (target.position + targetoffsetpos) - gun_camera.position; bool sees_target = false; if (dist < kMaxRange && Vector3.Dot(gun_camera.rotation * new Vector3(0.0f, -1.0f, 0.0f), rel_pos.normalized) > 0.7f) { RaycastHit hit = new RaycastHit(); if (!Physics.Linecast(gun_camera.position, target.position + targetoffsetpos, out hit, 1 << 0)) { sees_target = true; } } if (sees_target) { switch (ai_state) { case AIState.IDLE: ai_state = AIState.ALERT; audiosource_effect.PlayOneShot(sound_alert, 0.3f * Preferences.sound_volume); alert_delay = kAlertDelay; break; case AIState.AIMING: if (Vector3.Dot(gun_camera.rotation * new Vector3(0.0f, -1.0f, 0.0f), rel_pos.normalized) > 0.9f) { ai_state = AIState.FIRING; } target_pos = target.position + targetoffsetpos; break; case AIState.FIRING: target_pos = target.position + targetoffsetpos; break; case AIState.ALERT: alert_delay -= Time.deltaTime; if (alert_delay <= 0.0f) { ai_state = AIState.AIMING; } target_pos = target.position + targetoffsetpos; break; case AIState.ALERT_COOLDOWN: ai_state = AIState.ALERT; alert_delay = kAlertDelay; break; } } else { switch (ai_state) { case AIState.AIMING: case AIState.FIRING: case AIState.ALERT: ai_state = AIState.ALERT_COOLDOWN; alert_cooldown_delay = kAlertCooldownDelay; break; case AIState.ALERT_COOLDOWN: alert_cooldown_delay -= Time.deltaTime; if (alert_cooldown_delay <= 0.0f) { ai_state = AIState.IDLE; audiosource_effect.PlayOneShot(sound_unalert, 0.3f * Preferences.sound_volume); } break; } } switch (ai_state) { case AIState.IDLE: lightObject.color = new Color(0.0f, 0.0f, 1.0f); break; case AIState.AIMING: lightObject.color = new Color(1.0f, 0.0f, 0.0f); break; case AIState.ALERT: case AIState.ALERT_COOLDOWN: lightObject.color = new Color(1.0f, 1.0f, 0.0f); break; } } target.GetComponent <MusicScript>().AddDangerLevel(danger); } if (!camera_alive) { lightObject.intensity *= Mathf.Pow(0.01f, Time.deltaTime); } lensFlareObject.color = lightObject.color; lensFlareObject.brightness = lightObject.intensity; float target_pitch = (Mathf.Abs(rotation_y.vel) + Mathf.Abs(rotation_x.vel)) * 0.01f; target_pitch = Mathf.Clamp(target_pitch, 0.2f, 2.0f); audiosource_motor.pitch = Mathf.Lerp(audiosource_motor.pitch, target_pitch, Mathf.Pow(0.0001f, Time.deltaTime)); rotation_x.Update(); rotation_y.Update(); gun_pivot.localRotation = initial_turret_orientation; gun_pivot.localPosition = initial_turret_position; gun_pivot.RotateAround( point_pivot.position, point_pivot.rotation * new Vector3(1.0f, 0.0f, 0.0f), rotation_x.state); gun_pivot.RotateAround( point_pivot.position, point_pivot.rotation * new Vector3(0.0f, 1.0f, 0.0f), rotation_y.state); }
//--------------------------------------- // remove the spring, use animation blend tree for this...! much clean, very simple, WOW! private void SpringBank(float amount) { currentBanking += bankingSpring.Update(amount); }
void Update() { // Create new position at bind pose Vector3 rootJointPosition = new Vector3(); Vector3 rootJointScale = new Vector3(1, 1, 1); Quaternion rootJointRotation = rootJointStartRotation; List <Quaternion> neckJointRotations = new List <Quaternion>(neckJointStartRotations); List <Quaternion> wingJointRotations = new List <Quaternion>(wingJointStartRotations); List <Quaternion> legJointRotations = new List <Quaternion>(legJointStartRotations); // Update velocity velocity = transform.position - lastPosition; lastPosition = transform.position; // Add noise to head chaosPoint = new Vector3( Mathf.PerlinNoise(Time.time * animationSettings.chaosSpeed, 0.0f) - 0.5f, Mathf.PerlinNoise(Time.time * animationSettings.chaosSpeed, 302.3f) - 0.5f, Mathf.PerlinNoise(Time.time * animationSettings.chaosSpeed, 54.4f) - 0.5f ); chaosPoint *= animationSettings.chaos; // Sitting Offset rootJointPosition += new Vector3(0, -1 * Easing.Elastic.InOut(animationSettings.sittingBlend) * 0.25f, 0); float scaleValue = Mathf.Max(0.0f, Easing.Elastic.InOut(animationSettings.sittingBlend) - 1.0f) * 1.5f; rootJointScale += new Vector3(scaleValue, scaleValue, scaleValue); for (int i = 0; i < legJoints.Count; i++) { float legRotZ = Mathf.Lerp(0.0f, -90.0f, animationSettings.sittingBlend); Vector3 newLegAngles = new Vector3(0.0f, 0.0f, legRotZ); Quaternion localLegRotate = Quaternion.Inverse(legJointStartRotations[i]) * Quaternion.Euler(newLegAngles) * legJointStartRotations[i]; legJointRotations[i] *= localLegRotate; } // Head Bend for (int i = 0; i < headJoints.Count; i++) { float headRotZ = Mathf.Lerp(0.0f, -25.0f, animationSettings.headBend); float headRotX = Mathf.Lerp(-25.0f, 25.0f, animationSettings.headTurn / 2 + 0.5f); Vector3 newHeadAngles = new Vector3(headRotX, 0.0f, headRotZ); Quaternion localLegRotate = Quaternion.Inverse(neckJointStartRotations[i]) * Quaternion.Euler(newHeadAngles) * neckJointStartRotations[i]; neckJointRotations[i] *= localLegRotate; } // Wing Flap float heightBlend = -Mathf.Clamp((transform.position.y), 0.0f, 3.0f) / 3.0f; for (int i = 0; i < wingJoints.Count; i++) { float wingRotY = Mathf.Sin(Time.time * 20.0f) * 30.0f * heightBlend; Vector3 newHeadAngles = new Vector3(0.0f, 0.0f, wingRotY); Quaternion localLegRotate = Quaternion.Inverse(neckJointStartRotations[i]) * Quaternion.Euler(newHeadAngles) * neckJointStartRotations[i]; wingJointRotations[i] *= localLegRotate; } // Flying offset //float blend = -0.5f - transform.position.y; //rootJointPosition += new Vector3(0, (Easing.Elastic.In(blend) * animationSettings.flyOffset),0); //scaleValue = (1.0f - Mathf.Min(1.0f, Easing.Elastic.In(blend) + 1.0f)) * 1.5f; //rootJointScale += new Vector3(scaleValue, scaleValue, scaleValue); // Apply hop frame += Time.deltaTime * animationSettings.hopRate; Vector3 velocity2D = new Vector3(velocity.x, 0, velocity.z); if (frame >= 1.0f) { frame = 0.0f; hopHeight = Mathf.Clamp01(velocity2D.magnitude / animationSettings.maxVelocity); } rootJointPosition += animationSettings.moveY.Evaluate(frame) * hopHeight * animationSettings.hopHeight * Vector3.up * (1 + heightBlend); rootJointPosition += Mathf.Sin(frame * 6.2f) * animationSettings.hopHeight * 0.2f * Vector3.up * (heightBlend); // Rotate legs for (int i = 0; i < legJoints.Count; i++) { float legRotZ = Mathf.Cos(frame * 6.2f); legRotZ = Mathf.Lerp(0.0f, legRotZ, Mathf.Clamp01(velocity2D.magnitude / animationSettings.maxVelocity)); Vector3 newLegAngles = new Vector3(legRotZ, 0.0f, 0.0f); newLegAngles *= 90; newLegAngles *= 1 + heightBlend; Quaternion localLegRotate = Quaternion.Inverse(legJointStartRotations[i]) * Quaternion.Euler(newLegAngles) * legJointStartRotations[i]; legJointRotations[i] *= localLegRotate; } // Update springs rootSpring.Update(transform.position + chaosPoint); for (int i = 0; i < headSprings.Count; i++) { headSprings[i].Update(headJoints[i].transform.position + chaosPoint); } for (int i = 0; i < wingSprings.Count; i++) { wingSprings[i].Update(wingJoints[i].transform.position + chaosPoint); } // Rotate root based on spring float rotX = (rootSpring.position.z - rootJoint.transform.position.z); float rotZ = (rootSpring.position.x - rootJoint.transform.position.x); Vector3 newAngles = new Vector3(rotX, 0.0f, rotZ); newAngles *= 15.0f; Quaternion localRotate = Quaternion.Inverse(rootJointStartRotation) * Quaternion.Euler(newAngles) * rootJointStartRotation; rootJointRotation *= localRotate; // Rotate head joints based on spring for (int i = 0; i < headSprings.Count; i++) { float neckRotY = (headSprings[i].position.x - headJoints[i].transform.position.x); float neckRotZ = (headSprings[i].position.z - headJoints[i].transform.position.z); Vector3 newNeckAngles = new Vector3(0.0f, neckRotY, neckRotZ); newNeckAngles *= 30f; Quaternion localNeckRotate = Quaternion.Inverse(neckJointStartRotations[i]) * Quaternion.Euler(newNeckAngles) * neckJointStartRotations[i]; neckJointRotations[i] *= localNeckRotate; } // Rotate wings based on spring for (int i = 0; i < wingSprings.Count; i++) { float rotWingY = (wingSprings[i].position.z - wingJoints[i].transform.position.z); float rotWingZ = (wingSprings[i].position.y - wingJoints[i].transform.position.y); Vector3 newWingAngles = new Vector3(0, rotWingY, rotWingZ); newWingAngles *= 30f; Quaternion localWingRotate = Quaternion.Inverse(wingJointStartRotations[i]) * Quaternion.Euler(newWingAngles) * wingJointStartRotations[i]; wingJointRotations[i] *= localWingRotate; } // Apply new orientations rootJoint.transform.localPosition = rootJointPosition; rootJoint.transform.localRotation = rootJointRotation; rootJoint.transform.localScale = rootJointScale; for (int i = 0; i < neckJointRotations.Count; i++) { headJoints[i].transform.localRotation = neckJointRotations[i]; } for (int i = 0; i < wingJointRotations.Count; i++) { wingJoints[i].transform.localRotation = wingJointRotations[i]; } for (int i = 0; i < legJointRotations.Count; i++) { legJoints[i].transform.localRotation = legJointRotations[i]; } /* * if (SceneManager.GetActiveScene().buildIndex == 2) { * if (hovering) { * if (heightBlend <= 1.0f) { * FMODUnity.RuntimeManager.PlayOneShot(LandSound, transform.position); * hoverSound.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT); * * hovering = false; * } * } else { * if (heightBlend >= 1.0f) { * FMODUnity.RuntimeManager.PlayOneShot(JumpSound, transform.position); * hoverSound.start(); * hovering = true; * } * } * } */ }