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
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.
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.
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);
}
}
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);
}
}
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() {
}
}