- Home /
New to Unity: Trying to (loosely) simulate animal flight with separate buttons for each wing...
As the title says, I'm trying to loosely simulate the flight of an animal like a bird or butterfly, by having one button for each wing flap. I'm not so worried about the animations just yet, just the physics behind it.
Over the last several days, I've been trying to follow several tutorials and guides, and I've managed to make much progress, but I keep getting stuck on the rotation of the object. I've found a few glider guides and am using the code I found therein to get the object to glide.
Long story short, I'm trying to make it so that you can "flap" one of the wings by tapping one of the buttons repeatedly, thus allowing you to quickly bank the object. The closest I have come to solving the issue is with AddRelativeTorque.
The problem I'm having with that solution is that I want the object to slowly cease the rotation as well. To that end, a friend showed me PIDs, and I managed to implement one that works fairly well. I tried to use the calculation provided by the PID to apply an opposite force to the object. The problem with this solution was that I needed to calculate the rotation of the object and then calculate the mitigating force, but the angularVelocity.x is relative to the global scope, not to the object itself, which means that I can't get the speed the object is rotating around its own Z-axis in order to counteract the spin if the object isn't pointed exactly in the same direction as the global position.
Another solution I have tried is by holding a variable to store what should be the rotational speed (currentTorque in the linked code) and then applying opposing torque to the object based on the calculation of the PID. This too failed to function as intended, though it did appear to have some promise.
Then I tried using Slerp for rotation, but I simply do not understand what I am doing with Quaternions, or even how to define the starting position (which should be current position) and the ending position (which should be a few degrees to the left or right).
Lastly, I have tried using a simple transform.Rotate, which seems to work, but is incredibly jerky and not at all the sort of smooth rotation that I am looking for.
Sorry for the long post. I'm just curious if anyone can point me in the right direction to get these things on the path to progress. It feels like I've been making little to no progress on this over the last week, despite spending several hours on it (I even tried to download FreeFlight and use that, but I can't understand how to use it, and the docs are nonexistent). Thanks for any advice/assistance you can offer!
Here's the code I'm working with so far, if that helps at all.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ButterflyControlsv01 : MonoBehaviour {
// Wing vectors. Currently, both are the same for MVP testing.
// In future iteration, each wing will have separate X axial rotation added to their thrust vector.
float wingThrust = 500.0f;
float leftWingTorque = -100.0f;
float rightWingTorque = 100.0f;
float currentTorque;
public Transform from;
public Transform to;
public float speed = 0.1F;
// Use this for initialization
void Start () {
print ("ButterflyControls.cs loaded on " + gameObject.name);
}
// Update is called once per frame
void Update () {
Rigidbody rb = GetComponent<Rigidbody> ();
customPID pid = new customPID (50.0f, 50.0f, 50.0f);
from = transform;
to = transform;
float rollAmount = 0.0f;
float rollSpeed = 500.0f;
// float dot = Vector3.Dot(transform.right, Vector3.down);
// rb.AddRelativeTorque(Vector3.forward*dot*100*Time.deltaTime);
//
//Glider Transcription
//https://www.youtube.com/watch?v=_UvQGfddNFY
// Flight Control variables
float tilt = Input.GetAxis("Vertical") * 4;
float yaw = Input.GetAxis ("Yaw");
float roll = Input.GetAxis ("Horizontal");
// Yaw based on how we're rolled.
// float tip = (transform.right + Vector3.up).magnitude - 1.414214f;
// yaw -= tip;
// Tip based on if we are going backwards.
if ((transform.forward + rb.velocity).magnitude < 1.4) {
tilt += 0.3f;
}
if (tilt != 0) {
transform.Rotate (transform.right, tilt * Time.deltaTime * 10, Space.World);
}
if (roll != 0) {
transform.Rotate (transform.forward, roll * Time.deltaTime * -10, Space.World);
}
if (yaw != 0) {
transform.Rotate (Vector3.up, yaw * Time.deltaTime * 10, Space.World);
}
//End Glider Transcription
// Camera should remain relatively stable when following.
// Using moveCameTo and bias, we move the camera smoothly to track butterfly in flight
// Control Mapping
if (Input.GetKeyDown ("o") && Input.GetKeyDown ("p")) {
rb.AddForce (transform.forward * wingThrust / 2 + transform.up * wingThrust);
} else if (Input.GetKeyDown ("o")) {
// print ("Fire1 pressed.");
rb.AddForce (transform.forward * wingThrust / 10 + transform.up * wingThrust / 10 + transform.right * wingThrust / 5);
rollAmount -= rollSpeed;
// rb.AddRelativeTorque (new Vector3 (0, 0, leftWingTorque));
// currentTorque += leftWingTorque;
// transform.rotation = Quaternion.Slerp(from.rotation, to.rotation, Time.time * speed);
transform.Rotate(0, 0, rollAmount*Time.deltaTime);
} else if (Input.GetKeyDown ("p")) {
rb.AddForce (transform.forward * wingThrust / 10 + transform.up * wingThrust / 10 + -transform.right * wingThrust / 5);
rollAmount += rollSpeed;
// rb.AddRelativeTorque (new Vector3 (0, 0, rightWingTorque));
// currentTorque += rightWingTorque;
// transform.rotation = Quaternion.Slerp(from.rotation, to.rotation, Time.time * -speed);
transform.Rotate(0, 0, rollAmount*Time.deltaTime);
} else {
}
if (Input.GetKeyDown ("u")) {
transform.up = Vector3.up;
}
// float pidTorqueUpdate = pid.Update (0.0f, currentTorque, 0.1f);
// Vector3 pidUpdate = new Vector3 (0, 0, pidTorqueUpdate);
// rb.AddRelativeTorque (pidUpdate);
// print ("currentTorque = " + currentTorque);
// print ("pidTorqueUpdate = " + pidTorqueUpdate);
}
void FixedUpdate() {
//
// Rigidbody rb = GetComponent<Rigidbody> ();
//
//
// // Check the object's angular momentum and adjust it to level out.
//// print("rb.angularVelocity: " + rb.angularVelocity);
//
// customPID pid = new customPID (50.0f, 50.0f, 50.0f);
// // print("PID Update:" + pid.Update (0.0f, rb.angularVelocity.x, 5));
// float pidXUpdate = pid.Update(0.0f, rb.angularVelocity.x, 0.1f);
// float pidYUpdate = pid.Update(0.0f, rb.angularVelocity.y, 0.1f);
// float pidZUpdate = pid.Update(0.0f, rb.angularVelocity.z, 0.1f);
//
// //PID the X rotation if the butterfly is not on the ground
// float terrainHeightPlaneLocale = Terrain.activeTerrain.SampleHeight (transform.position);
// print(terrainHeightPlaneLocale + " + " + transform.position.y);
//
//
// if (terrainHeightPlaneLocale >= transform.position.y) {
// rb.velocity = Vector3.zero;
// } else {
// rb.AddRelativeTorque(new Vector3(0, 0, pidXUpdate);
// }
}
}
Your answer
Follow this Question
Related Questions
How come my spacecraft doesn't flip over smoothly in flight? 0 Answers
Torque towards Quaternion. 0 Answers
Determining the torque needed to rotate an object to a given rotation 8 Answers
How to properly do Twin Stick shooter controls with an XBOX controller? 1 Answer
Rotate an object relative to Camera 2 Answers