Orbital mechanisms in unity - c#

it's been a week since I've been trying to create, with the unity engine, an orbital system. I have found different solutions and methods but they don't satisfy the result I would like to see. Can someone tell me how to create a C# script with the addition of other details such as eccentricity?
Here is my "best" and latest code:
Orbit.cs
using UnityEngine;
using System.Collections;
public class Orbit : MonoBehaviour
{
public float axisX;
public float axisZ;
public float offsetY;
public Transform toOrbit;
public float vel = 0;
public bool clockwise;
float _vel = 0;
float timer = 0;
void Update () {
_vel = (vel / GetComponent<Rigidbody>().mass)*Time.fixedDeltaTime;
timer += _vel;
Rotate();
}
void Rotate() {
if(clockwise) {
float x = -Mathf.Cos(timer) * axisX;
float z = Mathf.Sin(timer) * axisZ;
Vector3 pos = new Vector3(x, offsetY, z);
transform.position = pos + toOrbit.position;
} else {
float x = Mathf.Cos(timer) * axisX;
float z = Mathf.Sin(timer) * axisZ;
Vector3 pos = new Vector3(x, offsetY, z);
transform.position = pos + toOrbit.position;
}
}
}
PS: I'm using Unity 5.2

Related

how to make a predictive trajectory arc while aiming?

I am trying to build a trajectory arc that would predict the trajectory path of the object, the drag and shoot seem fine but the arc is not working. initially I used an arrow for showing the direction of the movement of the object but later I tried to do the same using an array which would store 2 points and would keep updating after every iteration and it would result in an arc since I used the equations of motion to predict the positions after each frame.
***
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class movement: MonoBehaviour
{
public float velocity;
float time;
float x;
float y;
float tt;
float g;
Vector2 force;
public float power = 2.0f;
Vector3 startpoint;
Vector3 endpoint;
Camera cam;
public Vector2 maxpower;
public Vector2 minpower;
public Rigidbody2D rb;
Vector3 currentposition;
Vector3 sp;
LineRenderer lr;
int resolution = 10;
Vector3 newpoint;
// Start is called before the first frame update
void Start()
{
time = 0f;
g = Mathf.Abs(Physics2D.gravity.y);
cam = Camera.main;
lr = GetComponent<LineRenderer>();
}
// Update is called once per frame
void Update()
{
time += Time.deltaTime;
x = gameObject.transform.position.x + velocity * time;
tt = time * time;
y = gameObject.transform.position.y + (g * tt) / 2f;
if(Input.GetMouseButtonDown(0))
{
startpoint = cam.ScreenToWorldPoint(Input.mousePosition);
startpoint.z = 5;
}
if(Input.GetMouseButton(0))
{
sp = new Vector3(gameObject.transform.position.x, gameObject.transform.position.y, 5);
currentposition = cam.ScreenToWorldPoint(Input.mousePosition);
currentposition.z = 5;
LineRenderer(sp);
}
if (Input.GetMouseButtonUp(0))
{
endpoint = cam.ScreenToWorldPoint(Input.mousePosition);
endpoint.z = 5;
force = new Vector2(Mathf.Clamp(startpoint.x - endpoint.x, minpower.x, maxpower.x), Mathf.Clamp(startpoint.y - endpoint.y, minpower.y, maxpower.y));
rb.AddForce(force * power, ForceMode2D.Impulse);
x = x + velocity * time;
y = y + (g * tt) / 2f;
EndLine();
}
}
public void LineRenderer(Vector3 p)
{
lr.positionCount = resolution;
Vector3 arc = p;
for(int i=0;i<resolution;i++)
{
newpoint = calculate(arc, i / (float)resolution);
lr.SetPosition(i, newpoint);
arc = newpoint;
}
}
public Vector3 calculate(Vector3 point, float t)
{
point.x += velocity * t;
point.y += 0.5f * g * t * t;
return point;
}
public void EndLine()
{
lr.positionCount = 0;
}
}
***
This the code, any help is appreciated.
A bug that I see is your delta-time:
You call Calculate(arc, i/resolution), with i and resolution both being integers.
The parameter might be float time, but C# will first calculate i/resolution as an integer division, then convert the result to float. The result will be zero as long as i is less than resolution.
Change it to: i/(float)resolution to force a floating-point division.

How to make two objects inversely orbiting a point do so in a curve? Unity, C#

So I have this function attached to a sphere and in inverse one attached to another. They are rigged to emit a trail and the game object they are orbiting around is a sphere which is locked at 0,0,0. This is my code so far :
float t = 0;
float speed;
float width;
float height;
int cat = 0;
public GameObject orbit; //the object to orbit
// Use this for initialization
void Start()
{
speed = 2;
width = 5;
height = 2;
InvokeRepeating("test", .001f, .009f);
}
void test()
{
t += Time.deltaTime * speed;
Vector3 orbitv = orbit.transform.position;
float inc = .0000000001f;
inc += inc + t;
float angmom = .00001f;
angmom = angmom + t;
float x = orbitv.x + Mathf.Cos(t);
float z = orbitv.z + inc; //+ (Mathf.Cos(t)*Mathf.Sin(t));
float y = orbitv.y + Mathf.Sin(t);
transform.position = new Vector3(x, y, z);
}}
Which does this:
Instead of moving in the z direction exclusively, I'd like them to continue their current rotation, but in a circle around the sphere at 0,0,0 while staying at the same y level. Anyone have any ideas how I can do this?
Edit: This is what I'm trying to do:
Here's some code I cooked up for you.
All the movement is achieved with basic trigonometric functions and some easy vector math.
To tackle problems like these, try to break things down like I did with dividing the movement into circular/up-down & sideways. This lets you create the ring effect.
Adding more intertwined waves should be trivial by changing the phase of the oscillations and adding more trails.
public class Orbit : MonoBehaviour {
float t = 0;
public float speed;
public float width;
public float height;
public float radius;
int cat = 0;
public GameObject center; //the object to orbit
public Vector3 offset;
void Update()
{
t = Time.time * speed;
OrbitAround();
AddSideways();
}
void OrbitAround()
{
float x = radius * Mathf.Cos(t);
float y = Mathf.Sin(offset.y * t);
float z = radius * Mathf.Sin(t);
transform.position = new Vector3(x, y, z);
}
void AddSideways()
{
float x = Mathf.Cos(offset.x * t);
Vector3 dir = transform.position - center.transform.position;
transform.position += dir.normalized * x;
}
}
It should give you a trail like this:
You can play around with the Vec3 offset which changes the frequency of the oscillations and essentially lets you choose the number of rings.

Unity smooth camera zooming Rts game

Hello so i have a problem my camera is really sanping and i want it to zoom in and out smooth i looked at videos and forums but i dont know how can i get help this is the code for all the camera its for a rts game and all it does for now is you can zoom in out move the camera with your mouse being on the edges on the screen.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RtsCamera : MonoBehaviour {
public float scrollZone = 16;
public float scrollSpeed = 5;
public float zoomSensitivy = 15.0f;
public float xMax = 8;
public float xMin = 0;
public float yMax = 8;
public float yMin = 0;
public float zMax = 8;
public float zMin = 0;
private Vector3 desiredPosition;
private void Start()
{
desiredPosition = transform.position;
}
// Update is called once per frame
void Update () {
float x = 0, y = 0, z = 0;
float speed = scrollZone * Time.deltaTime;
if (Input.mousePosition.x < scrollZone)
x -= speed;
else if (Input.mousePosition.x > Screen.width - scrollZone)
x += speed;
if (Input.mousePosition.y < scrollZone)
z -= speed;
else if (Input.mousePosition.y > Screen.height - scrollZone)
z += speed;
y += Input.GetAxis("Mouse ScrollWheel")* zoomSensitivy;
Vector3 move = new Vector3(x,y,z) + transform.position;
move.x = Mathf.Clamp(move.x ,xMin ,xMax);
move.y = Mathf.Clamp(move.y ,yMin ,yMax);
move.z = Mathf.Clamp(move.z ,zMin ,zMax);
desiredPosition = move;
transform.position = Vector3.Lerp(transform.position, desiredPosition, 0.2f);
}
}

Why when pressing the Z key the ship is moving fast up and not forward?

I can use W S A D or arrow keys to turn the ship. But when i press on Z the ship fast moving up. When i press on X it will stop the ship on place.
I can't figure out how to make the ship move forward.
But nothing make the ship move forward.
I used a break point and i see in Start in the SpacecraftControl script on the line:
Debug.Log("Transform forward is : " + transform.forward);
Whem i put the mouse cursor on the forward of transform i see: 0.0,1.0,0.0
And inside the forward i see: x = 0 y = 0 and z = -1.192093E-07
Here is a small short video clip i recorded now showing what happen when running the game and then pressing on Z.
Please watch all the video the the Z pressing is start from second 14.
Video Clip
In my ship inspector i have: Transform, Local Rotation, Mesh Filter, Mesh Renderer, Animator, RigidBody > Gravity unchecked, Mesh Collider > Convex is checked and the scripts: Spacecraft Control and UserInput.
Then in the menu i went to: Edit > Project Settings > Input
In Input i addeed a new place one size to 19. And called the new Axes: Throttle
And the scripts first the SpacecraftControl:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
public class SpacecraftControl : MonoBehaviour
{
public float MaxEnginePower = 40f;
public float RollEffect = 50f;
public float PitchEffect = 50f;
public float YawEffect = 0.2f;
public float BankedTurnEffect = 0.5f;
public float AutoTurnPitch = 0.5f;
public float AutoRollLevel = 0.1f;
public float AutoPitchLevel = 0.1f;
public float AirBreaksEffect = 3f;
public float ThrottleChangeSpeed = 0.3f;
public float DragIncreaseFactor = 0.001f;
private float Throttle;
private bool AirBrakes;
private float ForwardSpeed;
private float EnginePower;
private float cur_MaxEnginePower;
private float RollAngle;
private float PitchAngle;
private float RollInput;
private float PitchInput;
private float YawInput;
private float ThrottleInput;
private float OriginalDrag;
private float OriginalAngularDrag;
private float AeroFactor = 1;
private bool Immobolized = false;
private float BankedTurnAmount;
private Rigidbody _rigidbody;
Collider[] cols;
void Start()
{
_rigidbody = GetComponent<Rigidbody> ();
OriginalDrag = _rigidbody.drag;
OriginalAngularDrag = _rigidbody.angularDrag;
for (int i = 0; i < transform.childCount; i++)
{
foreach (var componentsInChild in transform.GetChild(i).GetComponentsInChildren<WheelCollider>())
{
componentsInChild.motorTorque = 0.18f;
}
}
Debug.Log("Transform forward is : " + transform.forward);
}
public void Move(float rollInput, float pitchInput, float yawInput, float throttleInput, bool airBrakes)
{
this.RollInput = rollInput;
this.PitchInput = pitchInput;
this.YawInput = yawInput;
this.ThrottleInput = throttleInput;
this.AirBrakes = airBrakes;
ClampInput ();
CalculateRollandPitchAngles ();
AutoLevel ();
CalculateForwardSpeed ();
ControlThrottle ();
CalculateDrag ();
CalculateLinearForces ();
CalculateTorque ();
if (Throttle < 0.1f)
{
Vector3 currentVelocity = _rigidbody.velocity;
Vector3 newVelocity = currentVelocity * Time.deltaTime;
_rigidbody.velocity = currentVelocity - newVelocity;
}
}
void ClampInput()
{
RollInput = Mathf.Clamp (RollInput, -1, 1);
PitchInput = Mathf.Clamp (PitchInput, -1, 1);
YawInput = Mathf.Clamp (YawInput, -1, 1);
ThrottleInput = Mathf.Clamp (ThrottleInput, -1, 1);
}
void CalculateRollandPitchAngles()
{
Vector3 flatForward = transform.forward;
flatForward.y = 0;
if (flatForward.sqrMagnitude > 0)
{
flatForward.Normalize ();
Vector3 localFlatForward = transform.InverseTransformDirection (flatForward);
PitchAngle = Mathf.Atan2 (localFlatForward.y, localFlatForward.z);
Vector3 flatRight = Vector3.Cross (Vector3.up, flatForward);
Vector3 localFlatRight = transform.InverseTransformDirection (flatRight);
RollAngle = Mathf.Atan2 (localFlatRight.y, localFlatRight.x);
}
}
void AutoLevel()
{
BankedTurnAmount = Mathf.Sin (RollAngle);
if (RollInput == 0)
{
RollInput = -RollAngle * AutoRollLevel;
}
if (PitchInput == 0f)
{
PitchInput = -PitchAngle * AutoPitchLevel;
PitchInput -= Mathf.Abs (BankedTurnAmount * BankedTurnAmount * AutoTurnPitch);
}
}
void CalculateForwardSpeed()
{
Vector3 localVelocity = transform.InverseTransformDirection (_rigidbody.velocity);
ForwardSpeed = Mathf.Max (0, localVelocity.z);
}
void ControlThrottle()
{
if (Immobolized)
{
ThrottleInput = -0.5f;
}
Throttle = Mathf.Clamp01 (Throttle + ThrottleInput * Time.deltaTime * ThrottleChangeSpeed);
EnginePower = Throttle * MaxEnginePower;
}
void CalculateDrag()
{
float extraDrag = _rigidbody.velocity.magnitude * DragIncreaseFactor;
//_rigidbody.drag = (AirBrakes ? (OriginalDrag + ) * AirBreaksEffect : OriginalDrag * extraDrag);
_rigidbody.drag = AirBrakes ? (OriginalDrag * AirBreaksEffect) : OriginalDrag;
_rigidbody.drag *= extraDrag;
_rigidbody.angularDrag = OriginalAngularDrag * ForwardSpeed / 1000 + OriginalAngularDrag;
}
void CalculateLinearForces()
{
Vector3 forces = Vector3.zero;
forces += EnginePower * transform.forward;
_rigidbody.AddForce (forces);
}
void CalculateTorque()
{
Vector3 torque = Vector3.zero;
torque += PitchInput * PitchEffect * transform.right;
torque += YawInput * YawEffect * transform.up;
torque += -RollInput * RollEffect * transform.forward;
torque += BankedTurnAmount * BankedTurnEffect * transform.up;
_rigidbody.AddTorque (torque * AeroFactor);
}
public void Immobilize()
{
Immobolized = true;
}
public void Reset()
{
Immobolized = false;
}
}
And the UserInput script:
using UnityEngine;
using System.Collections;
public class UserInput : MonoBehaviour {
SpacecraftControl _spacecraftcontrol;
// Use this for initialization
void Start ()
{
_spacecraftcontrol = GetComponent<SpacecraftControl> ();
}
void FixedUpdate()
{
float roll = Input.GetAxis ("Horizontal");
float pitch = Input.GetAxis ("Vertical");
bool airBrakes = Input.GetButton ("Fire1");
float throttle = Input.GetAxis ("Throttle");
_spacecraftcontrol.Move (roll, pitch, 0, throttle, airBrakes);
}
}

Attempting to get a Hex grid

Im trying to get the hex prefab shapes that have already been created to line up with one another in a grid formation. I got the grid but I can't seem to get the hexes to fit into each other. Fixed the y%2 but the way it is setup now it crashes.
using UnityEngine;
using System.Collections;
public class boardObject : MonoBehaviour {
// Instantiates a prefab in a grid
public GameObject prefab;
public float gridX = 5f;
public float gridY = 5f;
public float spacing = 2f;
void Start() {
for (float y = 0.0f; y < gridY; y++) {
for (float x = 0.0f; x < gridX; x++) {
// THIS IS WHAT WAS MISSING FOR THIS TO ACTUALLY WORK MAKING A NEW VECTOR 3
// POSITION AFTER THE LOOP WAS SET UP. EACH NEW hex NEEDED HAVE A NEW POSITION. ->
Vector3 pos = new Vector3(x, 0.0f, y) * spacing;
//
//
//%2 thingy
if (y%2.0f==0.0f)
gridY += 0.5f;
else
gridY -= 0.0f;
Instantiate(prefab, pos, Quaternion.identity);
}
}
}
}
First pic is the one I have, second is the one I am trying to make.
This is the square board hex
This is what I am trying to do
using UnityEngine;
using System.Collections;
public class boardObject : MonoBehaviour {
// Instantiates a prefab in a grid
public GameObject prefab;
public float gridX = 5f;
public float gridY = 5f;
public float spacing = 2f;
public float xsize = 1.0f;
public float ysize = 1.0f;
void Start() {
for (float y = 0; y < gridY; y++) {
for (float x = 1; x < gridX; x++) { //<<<<<This is where the change was made to get it to work. x = 1 instead of 0.
Vector3 pos = new Vector3 (x * xsize, 0.0f, y * ysize) ;
Instantiate (prefab, pos, Quaternion.identity);
if (y % 2 == 0)
y += 1;
else
y -= 1;
}
}
}
void Update() {
}
}

Categories

Resources