initial upload
This commit is contained in:
@ -0,0 +1,35 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using static HeneGames.Airplane.SimpleAirPlaneController;
|
||||
|
||||
namespace HeneGames.Airplane
|
||||
{
|
||||
public class LandingArea : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Runway runway;
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
//Check if colliding object has airplane collider component
|
||||
if (other.transform.TryGetComponent<SimpleAirPlaneCollider>(out SimpleAirPlaneCollider _airPlaneCollider))
|
||||
{
|
||||
//Calculate that the plane is coming from the right direction
|
||||
Vector3 dirFromLandingAreaToPlayerPlane = (transform.position - _airPlaneCollider.transform.position).normalized;
|
||||
float _directionFloat = Vector3.Dot(transform.forward, dirFromLandingAreaToPlayerPlane);
|
||||
|
||||
//If direction is right start landing
|
||||
if (_directionFloat > 0.5f)
|
||||
{
|
||||
SimpleAirPlaneController _controller = _airPlaneCollider.controller;
|
||||
|
||||
runway.landingAdjuster.position = _controller.transform.position;
|
||||
|
||||
runway.AddAirplane(_controller);
|
||||
_controller.airplaneState = AirplaneState.Landing;
|
||||
_controller.AddLandingRunway(runway);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30a04da0bc23b7448b9719ce2d8c36ca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 228575
|
||||
packageName: Simple Airplane Controller
|
||||
packageVersion: 1.3
|
||||
assetPath: Assets/HeneGames/Simple Airplane Controller/Scripts/LandingArea.cs
|
||||
uploadId: 682889
|
||||
@ -0,0 +1,114 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HeneGames.Airplane
|
||||
{
|
||||
public class Runway : MonoBehaviour
|
||||
{
|
||||
private bool landingCompleted;
|
||||
private float landingSpeed;
|
||||
private SimpleAirPlaneController landingAirplaneController;
|
||||
private Vector3 landingAdjusterStartLocalPos;
|
||||
|
||||
[Header("Input")]
|
||||
[SerializeField] private KeyCode launchKey = KeyCode.Space;
|
||||
|
||||
[Header("Runway references")]
|
||||
public string runwayName = "Runway";
|
||||
[SerializeField] private LandingArea landingArea;
|
||||
public Transform landingAdjuster;
|
||||
[SerializeField] private Transform landingfinalPos;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
landingSpeed = 1f;
|
||||
landingAdjusterStartLocalPos = landingAdjuster.localPosition;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
//Airplane is landing (Landing area add airplane controller reference)
|
||||
if(landingAirplaneController != null)
|
||||
{
|
||||
//Set airplane to landing adjuster child
|
||||
landingAirplaneController.transform.SetParent(landingAdjuster.transform);
|
||||
|
||||
//Move landing adjuster to landing final pos position
|
||||
if(!landingCompleted)
|
||||
{
|
||||
landingSpeed += Time.deltaTime;
|
||||
landingAdjuster.localPosition = Vector3.Lerp(landingAdjuster.localPosition, landingfinalPos.localPosition, landingSpeed * Time.deltaTime);
|
||||
|
||||
float _distanceToLandingFinalPos = Vector3.Distance(landingAdjuster.position, landingfinalPos.position);
|
||||
if (_distanceToLandingFinalPos < 0.1f)
|
||||
{
|
||||
landingCompleted = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
landingAdjuster.localPosition = Vector3.Lerp(landingAdjuster.localPosition, landingfinalPos.localPosition, landingSpeed * Time.deltaTime);
|
||||
|
||||
//Launch airplane
|
||||
if (SimpleAirplaneInput.GetKeyDown(launchKey))
|
||||
{
|
||||
landingAirplaneController.airplaneState = SimpleAirPlaneController.AirplaneState.Takeoff;
|
||||
}
|
||||
|
||||
//Reset runway if landing airplane is taking off
|
||||
if (landingAirplaneController.airplaneState == SimpleAirPlaneController.AirplaneState.Flying)
|
||||
{
|
||||
landingAirplaneController.transform.SetParent(null);
|
||||
landingAirplaneController = null;
|
||||
landingCompleted = false;
|
||||
landingSpeed = 1f;
|
||||
landingAdjuster.localPosition = landingAdjusterStartLocalPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Landing area add airplane controller reference
|
||||
public void AddAirplane(SimpleAirPlaneController _simpleAirPlane)
|
||||
{
|
||||
landingAirplaneController = _simpleAirPlane;
|
||||
}
|
||||
|
||||
public bool AirplaneLandingCompleted()
|
||||
{
|
||||
if (landingAirplaneController != null)
|
||||
{
|
||||
if (landingAirplaneController.airplaneState != SimpleAirPlaneController.AirplaneState.Takeoff)
|
||||
{
|
||||
return landingCompleted;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool AirplaneIsLanding()
|
||||
{
|
||||
if(landingAirplaneController != null && !landingCompleted)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool AriplaneIsTakingOff()
|
||||
{
|
||||
if (landingAirplaneController != null)
|
||||
{
|
||||
if(landingAirplaneController.airplaneState == SimpleAirPlaneController.AirplaneState.Takeoff)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0bfdd5b211652cb418aa1d01956efde1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 228575
|
||||
packageName: Simple Airplane Controller
|
||||
packageVersion: 1.3
|
||||
assetPath: Assets/HeneGames/Simple Airplane Controller/Scripts/Runway.cs
|
||||
uploadId: 682889
|
||||
@ -0,0 +1,39 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
using HeneGames.Airplane;
|
||||
|
||||
namespace HeneGames.Airplane
|
||||
{
|
||||
public class RunwayUIManager : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Runway runway;
|
||||
[SerializeField] private TextMeshProUGUI debugText;
|
||||
[SerializeField] private GameObject uiContent;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if(runway.AirplaneIsLanding())
|
||||
{
|
||||
uiContent.SetActive(true);
|
||||
debugText.text = "Airplane is landing";
|
||||
}
|
||||
else if(runway.AirplaneLandingCompleted())
|
||||
{
|
||||
uiContent.SetActive(true);
|
||||
debugText.text = "Press space to launch";
|
||||
}
|
||||
else if(runway.AriplaneIsTakingOff())
|
||||
{
|
||||
uiContent.SetActive(true);
|
||||
debugText.text = "Airplane is taking off";
|
||||
}
|
||||
else
|
||||
{
|
||||
uiContent.SetActive(false);
|
||||
debugText.text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e157df09fb2dab44a83d748c03ad1e28
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 228575
|
||||
packageName: Simple Airplane Controller
|
||||
packageVersion: 1.3
|
||||
assetPath: Assets/HeneGames/Simple Airplane Controller/Scripts/RunwayUIManager.cs
|
||||
uploadId: 682889
|
||||
@ -0,0 +1,26 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HeneGames.Airplane
|
||||
{
|
||||
public class SimpleAirPlaneCollider : MonoBehaviour
|
||||
{
|
||||
public bool collideSometing;
|
||||
|
||||
[HideInInspector]
|
||||
public SimpleAirPlaneController controller;
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (other.GetComponentInParent<RingCheckpoint>() != null)
|
||||
return;
|
||||
|
||||
if (other.gameObject.GetComponent<SimpleAirPlaneCollider>() == null &&
|
||||
other.gameObject.GetComponent<LandingArea>() == null)
|
||||
{
|
||||
collideSometing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff51ae6c73555db4d9acc272efe08470
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 228575
|
||||
packageName: Simple Airplane Controller
|
||||
packageVersion: 1.3
|
||||
assetPath: Assets/HeneGames/Simple Airplane Controller/Scripts/SimpleAirPlaneCollider.cs
|
||||
uploadId: 682889
|
||||
@ -0,0 +1,680 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using Cinemachine;
|
||||
using System;
|
||||
|
||||
namespace HeneGames.Airplane
|
||||
{
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
public class SimpleAirPlaneController : MonoBehaviour
|
||||
{
|
||||
public enum AirplaneState
|
||||
{
|
||||
Flying,
|
||||
Landing,
|
||||
Takeoff,
|
||||
}
|
||||
|
||||
public Action crashAction;
|
||||
|
||||
#region Private variables
|
||||
|
||||
private List<SimpleAirPlaneCollider> airPlaneColliders = new List<SimpleAirPlaneCollider>();
|
||||
|
||||
private float maxSpeed = 0.6f;
|
||||
private float speedMultiplier;
|
||||
private float currentYawSpeed;
|
||||
private float currentPitchSpeed;
|
||||
private float currentRollSpeed;
|
||||
private float currentSpeed;
|
||||
private float currentEngineLightIntensity;
|
||||
private float currentEngineSoundPitch;
|
||||
private float lastEngineSpeed;
|
||||
|
||||
private bool planeIsDead;
|
||||
|
||||
private Rigidbody rb;
|
||||
private Runway currentRunway;
|
||||
|
||||
//Input variables
|
||||
private float inputH;
|
||||
private float inputV;
|
||||
private bool inputTurbo;
|
||||
private bool inputYawLeft;
|
||||
private bool inputYawRight;
|
||||
|
||||
#endregion
|
||||
|
||||
public AirplaneState airplaneState;
|
||||
|
||||
[Header("Wing trail effects")]
|
||||
[Range(0.01f, 1f)]
|
||||
[SerializeField] private float trailThickness = 0.045f;
|
||||
[SerializeField] private TrailRenderer[] wingTrailEffects;
|
||||
|
||||
[Header("Rotating speeds")]
|
||||
[Range(5f, 500f)]
|
||||
[SerializeField] private float yawSpeed = 50f;
|
||||
|
||||
[Range(5f, 500f)]
|
||||
[SerializeField] private float pitchSpeed = 100f;
|
||||
|
||||
[Range(5f, 500f)]
|
||||
[SerializeField] private float rollSpeed = 200f;
|
||||
|
||||
[Header("Rotating speeds multiplers when turbo is used")]
|
||||
[Range(0.1f, 5f)]
|
||||
[SerializeField] private float yawTurboMultiplier = 0.3f;
|
||||
|
||||
[Range(0.1f, 5f)]
|
||||
[SerializeField] private float pitchTurboMultiplier = 0.5f;
|
||||
|
||||
[Range(0.1f, 5f)]
|
||||
[SerializeField] private float rollTurboMultiplier = 1f;
|
||||
|
||||
[Header("Moving speed")]
|
||||
[Range(5f, 100f)]
|
||||
[SerializeField] private float defaultSpeed = 10f;
|
||||
|
||||
[Range(10f, 200f)]
|
||||
[SerializeField] private float turboSpeed = 20f;
|
||||
|
||||
[Range(0.1f, 50f)]
|
||||
[SerializeField] private float accelerating = 10f;
|
||||
|
||||
[Range(0.1f, 50f)]
|
||||
[SerializeField] private float deaccelerating = 5f;
|
||||
|
||||
[Header("Turbo settings")]
|
||||
[Range(0f, 100f)]
|
||||
[SerializeField] private float turboHeatingSpeed;
|
||||
|
||||
[Range(0f, 100f)]
|
||||
[SerializeField] private float turboCooldownSpeed;
|
||||
|
||||
[Header("Turbo heat values")]
|
||||
[Tooltip("Real-time information about the turbo's current temperature (do not change in the editor)")]
|
||||
[Range(0f, 100f)]
|
||||
[SerializeField] private float turboHeat;
|
||||
|
||||
[Tooltip("You can set this to determine when the turbo should cease overheating and become operational again")]
|
||||
[Range(0f, 100f)]
|
||||
[SerializeField] private float turboOverheatOver;
|
||||
|
||||
[SerializeField] private bool turboOverheat;
|
||||
|
||||
[Header("Sideway force")]
|
||||
[Range(0.1f, 15f)]
|
||||
[SerializeField] private float sidewaysMovement = 15f;
|
||||
|
||||
[Range(0.001f, 0.05f)]
|
||||
[SerializeField] private float sidewaysMovementXRot = 0.012f;
|
||||
|
||||
[Range(0.1f, 5f)]
|
||||
[SerializeField] private float sidewaysMovementYRot = 1.5f;
|
||||
|
||||
[Range(-1, 1f)]
|
||||
[SerializeField] private float sidewaysMovementYPos = 0.1f;
|
||||
|
||||
[Header("Engine sound settings")]
|
||||
[SerializeField] private AudioSource engineSoundSource;
|
||||
|
||||
[SerializeField] private float maxEngineSound = 1f;
|
||||
|
||||
[SerializeField] private float defaultSoundPitch = 1f;
|
||||
|
||||
[SerializeField] private float turboSoundPitch = 1.5f;
|
||||
|
||||
[Header("Engine propellers settings")]
|
||||
[Range(10f, 10000f)]
|
||||
[SerializeField] private float propelSpeedMultiplier = 100f;
|
||||
|
||||
[SerializeField] private GameObject[] propellers;
|
||||
|
||||
[Header("Turbine light settings")]
|
||||
[Range(0.1f, 20f)]
|
||||
[SerializeField] private float turbineLightDefault = 1f;
|
||||
|
||||
[Range(0.1f, 20f)]
|
||||
[SerializeField] private float turbineLightTurbo = 5f;
|
||||
|
||||
[SerializeField] private Light[] turbineLights;
|
||||
|
||||
[Header("Colliders")]
|
||||
[SerializeField] private Transform crashCollidersRoot;
|
||||
|
||||
[Header("Takeoff settings")]
|
||||
[Tooltip("How far must the plane be from the runway before it can be controlled again")]
|
||||
[SerializeField] private float takeoffLenght = 30f;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
//Setup speeds
|
||||
maxSpeed = defaultSpeed;
|
||||
currentSpeed = defaultSpeed;
|
||||
ChangeSpeedMultiplier(1f);
|
||||
|
||||
//Get and set rigidbody
|
||||
rb = GetComponent<Rigidbody>();
|
||||
rb.isKinematic = true;
|
||||
rb.useGravity = false;
|
||||
rb.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative;
|
||||
|
||||
SetupColliders(crashCollidersRoot);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
AudioSystem();
|
||||
HandleInputs();
|
||||
|
||||
switch (airplaneState)
|
||||
{
|
||||
case AirplaneState.Flying:
|
||||
FlyingUpdate();
|
||||
break;
|
||||
|
||||
case AirplaneState.Landing:
|
||||
LandingUpdate();
|
||||
break;
|
||||
|
||||
case AirplaneState.Takeoff:
|
||||
TakeoffUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#region Flying State
|
||||
|
||||
private void FlyingUpdate()
|
||||
{
|
||||
UpdatePropellersAndLights();
|
||||
|
||||
//Airplane move only if not dead
|
||||
if (!planeIsDead)
|
||||
{
|
||||
Movement();
|
||||
SidewaysForceCalculation();
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeWingTrailEffectThickness(0f);
|
||||
}
|
||||
|
||||
//Crash
|
||||
if (!planeIsDead && HitSometing())
|
||||
{
|
||||
Crash();
|
||||
}
|
||||
}
|
||||
|
||||
private void SidewaysForceCalculation()
|
||||
{
|
||||
float _mutiplierXRot = sidewaysMovement * sidewaysMovementXRot;
|
||||
float _mutiplierYRot = sidewaysMovement * sidewaysMovementYRot;
|
||||
|
||||
float _mutiplierYPos = sidewaysMovement * sidewaysMovementYPos;
|
||||
|
||||
//Right side
|
||||
if (transform.localEulerAngles.z > 270f && transform.localEulerAngles.z < 360f)
|
||||
{
|
||||
float _angle = (transform.localEulerAngles.z - 270f) / (360f - 270f);
|
||||
float _invert = 1f - _angle;
|
||||
|
||||
transform.Rotate(Vector3.up * (_invert * _mutiplierYRot) * Time.deltaTime);
|
||||
transform.Rotate(Vector3.right * (-_invert * _mutiplierXRot) * currentPitchSpeed * Time.deltaTime);
|
||||
|
||||
transform.Translate(transform.up * (_invert * _mutiplierYPos) * Time.deltaTime);
|
||||
}
|
||||
|
||||
//Left side
|
||||
if (transform.localEulerAngles.z > 0f && transform.localEulerAngles.z < 90f)
|
||||
{
|
||||
float _angle = transform.localEulerAngles.z / 90f;
|
||||
|
||||
transform.Rotate(-Vector3.up * (_angle * _mutiplierYRot) * Time.deltaTime);
|
||||
transform.Rotate(Vector3.right * (-_angle * _mutiplierXRot) * currentPitchSpeed * Time.deltaTime);
|
||||
|
||||
transform.Translate(transform.up * (_angle * _mutiplierYPos) * Time.deltaTime);
|
||||
}
|
||||
|
||||
//Right side down
|
||||
if (transform.localEulerAngles.z > 90f && transform.localEulerAngles.z < 180f)
|
||||
{
|
||||
float _angle = (transform.localEulerAngles.z - 90f) / (180f - 90f);
|
||||
float _invert = 1f - _angle;
|
||||
|
||||
transform.Translate(transform.up * (_invert * _mutiplierYPos) * Time.deltaTime);
|
||||
transform.Rotate(Vector3.right * (-_invert * _mutiplierXRot) * currentPitchSpeed * Time.deltaTime);
|
||||
}
|
||||
|
||||
//Left side down
|
||||
if (transform.localEulerAngles.z > 180f && transform.localEulerAngles.z < 270f)
|
||||
{
|
||||
float _angle = (transform.localEulerAngles.z - 180f) / (270f - 180f);
|
||||
|
||||
transform.Translate(transform.up * (_angle * _mutiplierYPos) * Time.deltaTime);
|
||||
transform.Rotate(Vector3.right * (-_angle * _mutiplierXRot) * currentPitchSpeed * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
private void Movement()
|
||||
{
|
||||
//Move forward
|
||||
transform.Translate(Vector3.forward * currentSpeed * Time.deltaTime);
|
||||
|
||||
//Store last speed
|
||||
lastEngineSpeed = currentSpeed;
|
||||
|
||||
//Rotate airplane by inputs
|
||||
transform.Rotate(Vector3.forward * -inputH * currentRollSpeed * Time.deltaTime);
|
||||
transform.Rotate(Vector3.right * inputV * currentPitchSpeed * Time.deltaTime);
|
||||
|
||||
//Rotate yaw
|
||||
if (inputYawRight)
|
||||
{
|
||||
transform.Rotate(Vector3.up * currentYawSpeed * Time.deltaTime);
|
||||
}
|
||||
else if (inputYawLeft)
|
||||
{
|
||||
transform.Rotate(-Vector3.up * currentYawSpeed * Time.deltaTime);
|
||||
}
|
||||
|
||||
//Accelerate and deacclerate
|
||||
if (currentSpeed < maxSpeed)
|
||||
{
|
||||
currentSpeed += accelerating * Time.deltaTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentSpeed -= deaccelerating * Time.deltaTime;
|
||||
}
|
||||
|
||||
//Turbo
|
||||
if (inputTurbo && !turboOverheat)
|
||||
{
|
||||
//Turbo overheating
|
||||
if(turboHeat > 100f)
|
||||
{
|
||||
turboHeat = 100f;
|
||||
turboOverheat = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Add turbo heat
|
||||
turboHeat += Time.deltaTime * turboHeatingSpeed;
|
||||
}
|
||||
|
||||
//Set speed to turbo speed and rotation to turbo values
|
||||
maxSpeed = turboSpeed;
|
||||
|
||||
currentYawSpeed = yawSpeed * yawTurboMultiplier;
|
||||
currentPitchSpeed = pitchSpeed * pitchTurboMultiplier;
|
||||
currentRollSpeed = rollSpeed * rollTurboMultiplier;
|
||||
|
||||
//Engine lights
|
||||
currentEngineLightIntensity = turbineLightTurbo;
|
||||
|
||||
//Effects
|
||||
ChangeWingTrailEffectThickness(trailThickness);
|
||||
|
||||
//Audio
|
||||
currentEngineSoundPitch = turboSoundPitch;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Turbo cooling down
|
||||
if(turboHeat > 0f)
|
||||
{
|
||||
turboHeat -= Time.deltaTime * turboCooldownSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
turboHeat = 0f;
|
||||
}
|
||||
|
||||
//Turbo cooldown
|
||||
if (turboOverheat)
|
||||
{
|
||||
if(turboHeat <= turboOverheatOver)
|
||||
{
|
||||
turboOverheat = false;
|
||||
}
|
||||
}
|
||||
|
||||
//Speed and rotation normal
|
||||
maxSpeed = defaultSpeed * speedMultiplier;
|
||||
|
||||
currentYawSpeed = yawSpeed;
|
||||
currentPitchSpeed = pitchSpeed;
|
||||
currentRollSpeed = rollSpeed;
|
||||
|
||||
//Engine lights
|
||||
currentEngineLightIntensity = turbineLightDefault;
|
||||
|
||||
//Effects
|
||||
ChangeWingTrailEffectThickness(0f);
|
||||
|
||||
//Audio
|
||||
currentEngineSoundPitch = defaultSoundPitch;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Landing State
|
||||
|
||||
public void AddLandingRunway(Runway _landingThisRunway)
|
||||
{
|
||||
currentRunway = _landingThisRunway;
|
||||
}
|
||||
|
||||
//My trasform is runway landing adjuster child
|
||||
private void LandingUpdate()
|
||||
{
|
||||
UpdatePropellersAndLights();
|
||||
|
||||
ChangeWingTrailEffectThickness(0f);
|
||||
|
||||
//Stop speed
|
||||
currentSpeed = Mathf.Lerp(currentSpeed, 0f, Time.deltaTime);
|
||||
|
||||
//Set local rotation to zero
|
||||
transform.localRotation = Quaternion.Lerp(transform.localRotation, Quaternion.Euler(0f,0f,0f), 2f * Time.deltaTime);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Takeoff State
|
||||
|
||||
private void TakeoffUpdate()
|
||||
{
|
||||
UpdatePropellersAndLights();
|
||||
|
||||
//Reset colliders
|
||||
foreach (SimpleAirPlaneCollider _airPlaneCollider in airPlaneColliders)
|
||||
{
|
||||
_airPlaneCollider.collideSometing = false;
|
||||
}
|
||||
|
||||
//Accelerate
|
||||
if (currentSpeed < turboSpeed)
|
||||
{
|
||||
currentSpeed += (accelerating * 2f) * Time.deltaTime;
|
||||
}
|
||||
|
||||
//Move forward
|
||||
transform.Translate(Vector3.forward * currentSpeed * Time.deltaTime);
|
||||
|
||||
//Far enough from the runaway go back to flying state
|
||||
float _distanceToRunway = Vector3.Distance(transform.position, currentRunway.transform.position);
|
||||
if(_distanceToRunway > takeoffLenght)
|
||||
{
|
||||
currentRunway = null;
|
||||
airplaneState = AirplaneState.Flying;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Audio
|
||||
private void AudioSystem()
|
||||
{
|
||||
if (engineSoundSource == null)
|
||||
return;
|
||||
|
||||
if (airplaneState == AirplaneState.Flying)
|
||||
{
|
||||
engineSoundSource.pitch = Mathf.Lerp(engineSoundSource.pitch, currentEngineSoundPitch, 10f * Time.deltaTime);
|
||||
|
||||
if (planeIsDead)
|
||||
{
|
||||
engineSoundSource.volume = Mathf.Lerp(engineSoundSource.volume, 0f, 10f * Time.deltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
engineSoundSource.volume = Mathf.Lerp(engineSoundSource.volume, maxEngineSound, 1f * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
else if (airplaneState == AirplaneState.Landing)
|
||||
{
|
||||
engineSoundSource.pitch = Mathf.Lerp(engineSoundSource.pitch, defaultSoundPitch, 1f * Time.deltaTime);
|
||||
engineSoundSource.volume = Mathf.Lerp(engineSoundSource.volume, 0f, 1f * Time.deltaTime);
|
||||
}
|
||||
else if (airplaneState == AirplaneState.Takeoff)
|
||||
{
|
||||
engineSoundSource.pitch = Mathf.Lerp(engineSoundSource.pitch, turboSoundPitch, 1f * Time.deltaTime);
|
||||
engineSoundSource.volume = Mathf.Lerp(engineSoundSource.volume, maxEngineSound, 1f * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
|
||||
private void UpdatePropellersAndLights()
|
||||
{
|
||||
if(!planeIsDead)
|
||||
{
|
||||
//Rotate propellers if any
|
||||
if (propellers.Length > 0)
|
||||
{
|
||||
RotatePropellers(propellers, currentSpeed * propelSpeedMultiplier);
|
||||
}
|
||||
|
||||
//Control lights if any
|
||||
if (turbineLights.Length > 0)
|
||||
{
|
||||
ControlEngineLights(turbineLights, currentEngineLightIntensity);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Rotate propellers if any
|
||||
if (propellers.Length > 0)
|
||||
{
|
||||
RotatePropellers(propellers, 0f);
|
||||
}
|
||||
|
||||
//Control lights if any
|
||||
if (turbineLights.Length > 0)
|
||||
{
|
||||
ControlEngineLights(turbineLights, 0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupColliders(Transform _root)
|
||||
{
|
||||
if (_root == null)
|
||||
return;
|
||||
|
||||
//Get colliders from root transform
|
||||
Collider[] colliders = _root.GetComponentsInChildren<Collider>();
|
||||
|
||||
//If there are colliders put components in them
|
||||
for (int i = 0; i < colliders.Length; i++)
|
||||
{
|
||||
//Change collider to trigger
|
||||
colliders[i].isTrigger = true;
|
||||
|
||||
GameObject _currentObject = colliders[i].gameObject;
|
||||
|
||||
//Add airplane collider to it and put it on the list
|
||||
SimpleAirPlaneCollider _airplaneCollider = _currentObject.AddComponent<SimpleAirPlaneCollider>();
|
||||
airPlaneColliders.Add(_airplaneCollider);
|
||||
|
||||
//Add airplane conroller reference to collider
|
||||
_airplaneCollider.controller = this;
|
||||
|
||||
//Add rigid body to it
|
||||
Rigidbody _rb = _currentObject.AddComponent<Rigidbody>();
|
||||
_rb.useGravity = false;
|
||||
_rb.isKinematic = true;
|
||||
_rb.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative;
|
||||
}
|
||||
}
|
||||
|
||||
private void RotatePropellers(GameObject[] _rotateThese, float _speed)
|
||||
{
|
||||
for (int i = 0; i < _rotateThese.Length; i++)
|
||||
{
|
||||
_rotateThese[i].transform.Rotate(Vector3.forward * -_speed * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
private void ControlEngineLights(Light[] _lights, float _intensity)
|
||||
{
|
||||
for (int i = 0; i < _lights.Length; i++)
|
||||
{
|
||||
if(!planeIsDead)
|
||||
{
|
||||
_lights[i].intensity = Mathf.Lerp(_lights[i].intensity, _intensity, 10f * Time.deltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
_lights[i].intensity = Mathf.Lerp(_lights[i].intensity, 0f, 10f * Time.deltaTime);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeWingTrailEffectThickness(float _thickness)
|
||||
{
|
||||
for (int i = 0; i < wingTrailEffects.Length; i++)
|
||||
{
|
||||
wingTrailEffects[i].startWidth = Mathf.Lerp(wingTrailEffects[i].startWidth, _thickness, Time.deltaTime * 10f);
|
||||
}
|
||||
}
|
||||
|
||||
private bool HitSometing()
|
||||
{
|
||||
for (int i = 0; i < airPlaneColliders.Count; i++)
|
||||
{
|
||||
if (airPlaneColliders[i].collideSometing)
|
||||
{
|
||||
//Reset colliders
|
||||
foreach(SimpleAirPlaneCollider _airPlaneCollider in airPlaneColliders)
|
||||
{
|
||||
_airPlaneCollider.collideSometing = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
|
||||
public virtual void Crash()
|
||||
{
|
||||
//Invoke action
|
||||
crashAction?.Invoke();
|
||||
|
||||
//Set rigidbody to non cinematic
|
||||
rb.isKinematic = false;
|
||||
rb.useGravity = true;
|
||||
rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
|
||||
|
||||
//Add last speed to rb
|
||||
rb.AddForce(transform.forward * lastEngineSpeed, ForceMode.VelocityChange);
|
||||
|
||||
//Change every collider trigger state and remove rigidbodys
|
||||
for (int i = 0; i < airPlaneColliders.Count; i++)
|
||||
{
|
||||
airPlaneColliders[i].GetComponent<Collider>().isTrigger = false;
|
||||
Destroy(airPlaneColliders[i].GetComponent<Rigidbody>());
|
||||
}
|
||||
|
||||
//Kill player
|
||||
planeIsDead = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Variables
|
||||
|
||||
/// <summary>
|
||||
/// Returns a percentage of how fast the current speed is from the maximum speed between 0 and 1
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public float PercentToMaxSpeed()
|
||||
{
|
||||
float _percentToMax = (currentSpeed * speedMultiplier) / turboSpeed;
|
||||
|
||||
return _percentToMax;
|
||||
}
|
||||
|
||||
public bool PlaneIsDead()
|
||||
{
|
||||
return planeIsDead;
|
||||
}
|
||||
|
||||
public bool UsingTurbo()
|
||||
{
|
||||
if(maxSpeed == turboSpeed)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public float CurrentSpeed()
|
||||
{
|
||||
return currentSpeed * speedMultiplier;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a turbo heat between 0 and 100
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public float TurboHeatValue()
|
||||
{
|
||||
return turboHeat;
|
||||
}
|
||||
|
||||
public bool TurboOverheating()
|
||||
{
|
||||
return turboOverheat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// With this you can adjust the default speed between one and zero
|
||||
/// </summary>
|
||||
/// <param name="_speedMultiplier"></param>
|
||||
public void ChangeSpeedMultiplier(float _speedMultiplier)
|
||||
{
|
||||
if(_speedMultiplier < 0f)
|
||||
{
|
||||
_speedMultiplier = 0f;
|
||||
}
|
||||
|
||||
if(_speedMultiplier > 1f)
|
||||
{
|
||||
_speedMultiplier = 1f;
|
||||
}
|
||||
|
||||
speedMultiplier = _speedMultiplier;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Inputs
|
||||
|
||||
private void HandleInputs()
|
||||
{
|
||||
inputH = SimpleAirplaneInput.Horizontal;
|
||||
inputV = SimpleAirplaneInput.Vertical;
|
||||
inputYawLeft = SimpleAirplaneInput.YawLeft;
|
||||
inputYawRight = SimpleAirplaneInput.YawRight;
|
||||
inputTurbo = SimpleAirplaneInput.Turbo;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d236260ee0d659a4383b8680de7ec2ad
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 228575
|
||||
packageName: Simple Airplane Controller
|
||||
packageVersion: 1.3
|
||||
assetPath: Assets/HeneGames/Simple Airplane Controller/Scripts/SimpleAirPlaneController.cs
|
||||
uploadId: 682889
|
||||
@ -0,0 +1,77 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Cinemachine;
|
||||
using static HeneGames.Airplane.SimpleAirPlaneController;
|
||||
|
||||
namespace HeneGames.Airplane
|
||||
{
|
||||
public class SimpleAirplaneCamera : MonoBehaviour
|
||||
{
|
||||
private CinemachineBrain brain;
|
||||
|
||||
[Header("References")]
|
||||
[SerializeField] private SimpleAirPlaneController airPlaneController;
|
||||
[SerializeField] private CinemachineFreeLook freeLook;
|
||||
|
||||
[Header("Camera values")]
|
||||
[SerializeField] private float cameraDefaultFov = 60f;
|
||||
[SerializeField] private float cameraTurboFov = 40f;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
airPlaneController.crashAction += Crash;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
airPlaneController.crashAction -= Crash;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
brain = GetComponent<CinemachineBrain>();
|
||||
|
||||
//Lock and hide mouse
|
||||
Cursor.lockState = CursorLockMode.Locked;
|
||||
Cursor.visible = false;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
CameraFovUpdate();
|
||||
}
|
||||
|
||||
private void CameraFovUpdate()
|
||||
{
|
||||
//Turbo
|
||||
if(!airPlaneController.PlaneIsDead() && airPlaneController.airplaneState == AirplaneState.Flying)
|
||||
{
|
||||
if (SimpleAirplaneInput.Turbo && !airPlaneController.TurboOverheating())
|
||||
{
|
||||
ChangeCameraFov(cameraTurboFov);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeCameraFov(cameraDefaultFov);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeCameraFov(cameraDefaultFov);
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeCameraFov(float _fov)
|
||||
{
|
||||
float _deltatime = Time.deltaTime * 100f;
|
||||
freeLook.m_Lens.FieldOfView = Mathf.Lerp(freeLook.m_Lens.FieldOfView, _fov, 0.05f * _deltatime);
|
||||
}
|
||||
|
||||
private void Crash()
|
||||
{
|
||||
//Change update method after crash
|
||||
brain.m_BlendUpdateMethod = CinemachineBrain.BrainUpdateMethod.FixedUpdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea6bf9033feb8da4b809d7e517cd3e62
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 228575
|
||||
packageName: Simple Airplane Controller
|
||||
packageVersion: 1.3
|
||||
assetPath: Assets/HeneGames/Simple Airplane Controller/Scripts/SimpleAirplaneCamera.cs
|
||||
uploadId: 682889
|
||||
@ -0,0 +1,123 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace HeneGames.Airplane
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads flight controls via the Input System (works when the project uses the new Input System).
|
||||
/// Falls back to legacy Input when the old backend is enabled.
|
||||
/// </summary>
|
||||
internal static class SimpleAirplaneInput
|
||||
{
|
||||
public static float Horizontal => ReadAxis("Horizontal", ReadHorizontalKeyboard);
|
||||
|
||||
public static float Vertical => ReadAxis("Vertical", ReadVerticalKeyboard);
|
||||
|
||||
public static bool YawLeft => IsPressed(Key.Q, KeyCode.Q);
|
||||
|
||||
public static bool YawRight => IsPressed(Key.E, KeyCode.E);
|
||||
|
||||
public static bool Turbo => IsPressed(Key.LeftShift, KeyCode.LeftShift);
|
||||
|
||||
public static bool GetKeyDown(KeyCode keyCode)
|
||||
{
|
||||
var keyboard = Keyboard.current;
|
||||
if (keyboard != null && TryMapKey(keyCode, out Key key))
|
||||
return keyboard[key].wasPressedThisFrame;
|
||||
|
||||
#if ENABLE_LEGACY_INPUT_MANAGER
|
||||
return Input.GetKeyDown(keyCode);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool GetKey(KeyCode keyCode)
|
||||
{
|
||||
var keyboard = Keyboard.current;
|
||||
if (keyboard != null && TryMapKey(keyCode, out Key key))
|
||||
return keyboard[key].isPressed;
|
||||
|
||||
#if ENABLE_LEGACY_INPUT_MANAGER
|
||||
return Input.GetKey(keyCode);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
private static float ReadAxis(string axisName, System.Func<float> readKeyboard)
|
||||
{
|
||||
var keyboard = Keyboard.current;
|
||||
if (keyboard != null)
|
||||
{
|
||||
float value = readKeyboard();
|
||||
if (value != 0f)
|
||||
return value;
|
||||
}
|
||||
|
||||
#if ENABLE_LEGACY_INPUT_MANAGER
|
||||
return Input.GetAxisRaw(axisName);
|
||||
#else
|
||||
return 0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
private static float ReadHorizontalKeyboard()
|
||||
{
|
||||
var keyboard = Keyboard.current;
|
||||
float value = 0f;
|
||||
if (keyboard.aKey.isPressed || keyboard.leftArrowKey.isPressed)
|
||||
value -= 1f;
|
||||
if (keyboard.dKey.isPressed || keyboard.rightArrowKey.isPressed)
|
||||
value += 1f;
|
||||
return value;
|
||||
}
|
||||
|
||||
private static float ReadVerticalKeyboard()
|
||||
{
|
||||
var keyboard = Keyboard.current;
|
||||
float value = 0f;
|
||||
if (keyboard.sKey.isPressed || keyboard.downArrowKey.isPressed)
|
||||
value -= 1f;
|
||||
if (keyboard.wKey.isPressed || keyboard.upArrowKey.isPressed)
|
||||
value += 1f;
|
||||
return value;
|
||||
}
|
||||
|
||||
private static bool IsPressed(Key inputSystemKey, KeyCode legacyKey)
|
||||
{
|
||||
var keyboard = Keyboard.current;
|
||||
if (keyboard != null && keyboard[inputSystemKey].isPressed)
|
||||
return true;
|
||||
|
||||
#if ENABLE_LEGACY_INPUT_MANAGER
|
||||
return Input.GetKey(legacyKey);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
private static bool TryMapKey(KeyCode keyCode, out Key key)
|
||||
{
|
||||
switch (keyCode)
|
||||
{
|
||||
case KeyCode.Space: key = Key.Space; return true;
|
||||
case KeyCode.LeftShift: key = Key.LeftShift; return true;
|
||||
case KeyCode.RightShift: key = Key.RightShift; return true;
|
||||
case KeyCode.Q: key = Key.Q; return true;
|
||||
case KeyCode.E: key = Key.E; return true;
|
||||
case KeyCode.W: key = Key.W; return true;
|
||||
case KeyCode.A: key = Key.A; return true;
|
||||
case KeyCode.S: key = Key.S; return true;
|
||||
case KeyCode.D: key = Key.D; return true;
|
||||
case KeyCode.UpArrow: key = Key.UpArrow; return true;
|
||||
case KeyCode.DownArrow: key = Key.DownArrow; return true;
|
||||
case KeyCode.LeftArrow: key = Key.LeftArrow; return true;
|
||||
case KeyCode.RightArrow: key = Key.RightArrow; return true;
|
||||
default:
|
||||
key = Key.None;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9327ebffbb76b7945b7b7c0e5a868513
|
||||
Reference in New Issue
Block a user