Unity C# unusual obit - c#

I was making a game about space, like KSP and other space simulator game.
This is the normal orbit.
The normal orbit is a circle.
But this is my orbit .
I try using Collider2D and Point effector2D to create gravity but it is not well too.
This is my code:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Gravity : MonoBehaviour {
public float Mass;
private List<GameObject> InRangeObjects;
// Use this for initialization
void Start () {
InRangeObjects = new List<GameObject>();
}
// Update is called once per frame
void Update () {
ApplyGravity();
}
void OnTriggerStay2D(Collider2D col)
{
List<GameObject> InRangeObjectstemp = new List<GameObject>();
InRangeObjectstemp.Add(col.gameObject);
InRangeObjects = InRangeObjectstemp;
////////////////////////////////////
}
public void ApplyGravity()
{
foreach (GameObject Ga in InRangeObjects)
{
float distance = (Ga.transform.position - transform.position).magnitude;
if (Ga.GetComponent<TotalDataStorer>().UseInGameGravity == true)
{
float GravitationalPule = (6.673e-11f * ((Mass * Ga.GetComponent<Rigidbody2D>().mass) / (distance * distance))) * Time.deltaTime;
Debug.Log(GravitationalPule);
Vector3 temp = Ga.transform.position - transform.position;
Ga.GetComponent<Rigidbody2D>().AddForce(new Vector2(temp.x, temp.y) * GravitationalPule * -1) ;
}
}
}
}
I have a flower like orbit, how can I fix this?

The problem is your object is not traveling fast enough, that is an orbit of a slow moving outer object not a regular "circular" orbit, you will have to tweak the speed at which your object is moving. In general you got everything right, it is an orbit, and it is mathematically correct, just you need to get the initial conditions correct.
Oh and you spelled pull wrong in GravitationalPule, it is GravitationalPull.

Related

2D character is not moving in Unity, using the keys. Script seems to be correct. Please verify the code and the Inspector

![This is how my Inspector looks like](inspector image)
And here's the script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
public float speed = 10f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector2 Movement = Vector2.zero;
Movement.y = v;
Movement.x = h;
transform.Translate(Movement * speed * Time.deltaTime);
}
} // class
And no, increasing the speed to check if its just not moving really slow, did not help :(
You need to set correct value in inspector or in start funciton.
void Start()
{
speed = 10f;
}
inspector image

Object spawning itself when other object is close enough

How can I make the water in my game (picture below) clone itself and put the clone right next to itself, when another object (the player) is close enough?
Scene:scene
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Paralax : MonoBehaviour
{
// The player
public Transform player;
// The distance from the player needed to copy itself
public float distanceToSpawn = 30f;
// The object
public Transform trans;
bool alreadySpawned;
private void Update()
{
if(!alreadySpawned)
{
// Getting the distance between
float dst = Mathf.Abs(player.position.x - transform.position.x);
if (dst < distanceToSpawn)
{
Transform newTrans = trans;
newTrans.position = (transform.position - new Vector3(/* negative width of the water so it copies itself to the left*/-15.72f, 0f, 0f));
Instantiate(gameObject, newTrans);
alreadySpawned = true;
}
}
}
}
But for some reason the water I placed in the scene is just getting away from the player, and not copying itself. Can anyone help me?
It sounds like trans was maybe the same as transform and therefore you move this very same object away before you spawn a new clone of it as a child.
You would probably rather simply do
var newObj = Instantiate(gameObject, transform);
newObj.transform.position = transform.position + Vector3.left * 15.72f;

Cant Change Friction of Player In Unity2D

I am extremely new to both Unity and C# and have been working on it for a few days. I'm currently trying to stop my player from sliding and to do this I've set the friction value of the players material high so that it doesn't slide. This however creates an issue where my character travels entirely too fast. To get around this I created a child object with a BoxCollider2D tagged as Friction Controller that I can modify. I get a code that changes the friction value of the physics material to 0 when i start moving and 100 when am supposed to stop. The problem is that while this updates the material itself it does not affect the box colliders settings. Does anybody know a solution for this?
using System.Collections.Generic;
using System.Collections.Specialized;
using UnityEngine;
public class Player_Movement : MonoBehaviour
{
GameObject frictionController;
public BoxCollider2D collider;
public float speed = 400f;
public float jumpForce;
private float friction;
private Rigidbody2D rb2d;
private bool isMoving;
// Start is called before the first frame update
void Start()
{
rb2d = GetComponent<Rigidbody2D> ();
}
// Update is called once per frame
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
Vector2 movement = new Vector2(moveHorizontal,0);
rb2d.AddForce(movement * speed);
}
void Update()
{
frictionController = GameObject.FindWithTag("Friction Controller");
collider = frictionController.GetComponent<BoxCollider2D>();
if (Input.GetKey("a") || (Input.GetKey("d")))
{
{ Debug.Log("Pressed Button"); }
collider.sharedMaterial.friction = 0;
} else { collider.sharedMaterial.friction = 100; }
///This part isn't complete yet
float moveVertical = Input.GetAxis("Vertical");
Vector2 jump = new Vector2(0, moveVertical);
if (Input.GetKeyDown("space"))
{
rb2d.AddForce(Vector3.up * jumpForce);
}
}
}
I'm not sure that your approach is a particularly good one and is likely to give you problems later on. Since you're using the physics system, a better approach would be to apply a force to your Rigidbody that is the OPPOSITE of its velocity when want it to come to a stop.
Nevertheless here is a solution that effectively does what you want to do using a similar approach to what you're attempting. Rather than manipulating the physics material properties, this solution manipulates the drag value of the rigidbody.
public class Player_Movement : MonoBehaviour
{
private Rigidbody2D rb2d;
private float speed = 100f;
void Start()
{
rb2d = GetComponent<Rigidbody2D> ();
}
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
Vector2 movement = new Vector2(moveHorizontal,0);
rb2d.AddForce(movement * speed);
}
void Update()
{
if (Input.GetKey(KeyCode.A) || (Input.GetKey(KeyCode.D)))
{
rb2d.drag = 5; // Adjust this value to modify speed
}
else
{
rb2d.drag = 100; // Adjust this value to modify slippery-ness
}
}
}

Unity How to limit Spawner?

I am working on a game like 2 cars. So there will be two lines and I have used two object spawner which is going to spawn two shapes, i,e Circle and Square. So when player collides with circle score should update. And when Square falls player is supposed to avoid it by going to another lane. But what is the problem is something both the spawner spawns square simultaneously or with small gap. So player is not able to escape. Any solution for this. Well I guess it does not help much but here is my script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Instantiter : MonoBehaviour {
public GameObject[] gameobject;
public float SpawnDelay= 3f;
private GameObject objectkeeper;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
float Spawntime = SpawnDelay * Time.deltaTime; // 1 *1/60
if (Random.value < Spawntime) {
Spawn ();
}
}
void Spawn(){
int number = Random.Range (0, 2);// creating random number between 0 and 1
objectkeeper = Instantiate (gameobject [number], this.transform.position, Quaternion.identity) as GameObject;
objectkeeper.transform.parent = this.transform;
}
void OnDrawGizmos(){
Gizmos.DrawWireSphere (this.transform.position, 0.5f);
}
}
Thank you for your time and consideration
Try this,
It will only spawn one object at a time between the min-max period
It does not cleanup old objects
It allows for more than 2 prefabs
I tried keeping to your code format as much as possible
Disclaimer : I do not currently have a visual studio/mono develop open (in a boring meeting) so i have not tested this :]
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Instantiter : MonoBehaviour {
public GameObject[] prefabs;
// Adding a min-max allows full control of spawning behaviour without editing code again.
// for a fixed time use the same value
public float MinimumSpawnDelay = 3f;
public float MaximumSpawnDelay = 6f;
private GameObject spawnedObject;
// Made this static so it retains it's value across all instances of this script.
// If you want each Instantiter object to function on it's own, remove the static keyword
private static float nextSpawnTime;
// Use this for initialization
void Start () {
// Artificial delay so we do not spawn an object directly at startup
SetNextSpawnTime();
}
// Update is called once per frame
void Update () {
if (Time.time >= nextSpawnTime) {
Spawn ();
}
}
void Spawn(){
// allows you to add more objects to the prefabs array without changing code.
var prefabToSpawn = prefabs[Ranom.Range(0, prefabs.Length)];
spawnedObject = Instantiate (prefabToSpawn, transform.position, Quaternion.identity);
spawnedObject.transform.parent = transform;
SetNextSpawnTime();
}
void OnDrawGizmos() {
Gizmos.DrawWireSphere (transform.position, 0.5f);
}
void SetNextSpawnTime(){
// a simple variable to hold when we should spawn another object, efficient.
nextSpawnTime = Time.time + Random.Range(MinimumSpawnDelay, MaximumSpawnDelay);
}
}
Try using a static variable -
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Instantiter : MonoBehaviour {
public GameObject[] gameobject;
public float SpawnDelay= 3f;
private GameObject objectkeeper;
// Static variable shared across all instances of this script
public static float nextSpawn = 0f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
// check if SpawnDelay duration has passed
if (Time.time >= nextSpawn) {
// Now spawn after ramdom time
float Spawntime = SpawnDelay * Time.deltaTime; // 1 *1/60
if (Random.value < Spawntime) {
Spawn ();
}
}
}
void Spawn(){
int number = Random.Range (0, 2);// creating random number between 0 and 1
objectkeeper = Instantiate (gameobject [number], this.transform.position, Quaternion.identity) as GameObject;
objectkeeper.transform.parent = this.transform;
// Set the nextSpawn time to after SpawnDelay Duration
nextSpawn = Time.time + SpawnDelay;
}
void OnDrawGizmos(){
Gizmos.DrawWireSphere (this.transform.position, 0.5f);
}
}

Unity 3D How to setup Turret Auto Aim? C#

what i't trying to achieve is have my turrent rotate and follow an "Enemy".
At the moment it detects the enemy but it is not rotating and I don't know why.
The bullet it a prefab i drag in, there has to be a better way to do this? Anyone have any suggestions please?
At the moment the bullet never triggers, but the log Shoot and does...and the rotate doesn't work.
Here is what i have
using UnityEngine;
using System.Collections;
public class TurretController : MonoBehaviour {
public Rigidbody bulletPrefab;
private Transform target;
private GameObject bullet;
private float nextFire;
private Quaternion targetPos;
void OnTriggerEnter(Collider otherCollider) {
if (otherCollider.CompareTag("Enemy"))
{
Debug.Log ("in");
target = otherCollider.transform;
StartCoroutine ("Fire");
}
}
void OnTriggerExit(Collider otherCollider) {
if (otherCollider.CompareTag("Enemy"))
{
Debug.Log ("out");
target = null;
StopCoroutine("Fire"); // aborts the currently running Fire() coroutine
}
}
IEnumerator Fire()
{
while (target != null)
{
nextFire = Time.time + 0.5f;
while (Time.time < nextFire)
{
// smooth the moving of the turret
targetPos = Quaternion.LookRotation (target.position);
transform.rotation = Quaternion.Slerp(transform.rotation, targetPos, Time.deltaTime * 5);
yield return new WaitForEndOfFrame();
}
// fire!
Debug.Log ("shoot");
bullet = Instantiate(bulletPrefab, transform.position, transform.rotation) as GameObject;
//bullet.rigidbody.velocity = transform.forward * bulletSpeed;
}
}
}
I tried to change the instantiate part by using this instead
bullet = (GameObject)Instantiate(bulletPrefab, transform.position, transform.rotation);
bullet.GetComponent<Bullet>().target = target.transform;
But then i just get errors like "InvalidCastException: Cannot cast from source type to destination type.
TurretController+c__Iterator0.MoveNext () (at Assets/Scripts/TurretController.cs:44)"
BTW, here's the turret rotation code I used in my project (shared with permission):
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Turret : MonoBehaviour
{
[SerializeField]
private float turnRateRadians = 2 * Mathf.PI;
[SerializeField]
private Transform turretTop; // the gun part that rotates
[SerializeField]
private Transform bulletSpawnPoint;
private Enemy target;
void Update()
{
TargetEnemy();
}
void TargetEnemy()
{
if (target == null || target.health <= 0)
target = Enemy.GetClosestEnemy(turretTop, filter: enemy => enemy.health > 0);
if (target != null)
{
Vector3 targetDir = target.transform.position - transform.position;
// Rotating in 2D Plane...
targetDir.y = 0.0f;
targetDir = targetDir.normalized;
Vector3 currentDir = turretTop.forward;
currentDir = Vector3.RotateTowards(currentDir, targetDir, turnRateRadians*Time.deltaTime, 1.0f);
Quaternion qDir = new Quaternion();
qDir.SetLookRotation(currentDir, Vector3.up);
turretTop.rotation = qDir;
}
}
}
class Enemy : MonoBehaviour
{
public float health = 0;
private static HashSet<Enemy> allEnemies = new HashSet<Enemy>();
void Awake()
{
allEnemies.Add(this);
}
void OnDestroy()
{
allEnemies.Remove(this);
}
/// <summary>
/// Get the closest enemy to some transform, optionally filtering
/// (for example, enemies that aren't dead, or enemies of a certain type).
/// </summary>
public static Enemy GetClosestEnemy(Transform referenceTransform, System.Predicate<Enemy> filter=null)
{
// Left as an exercise for the reader.
// Remember not to use Vector3.Distance in a loop if you don't need it. ;-)
// return allEnemies[0];
}
}
First problem: the bullet prefab. The variable type is RigidBody. If you want to treat it as a game object, the variable must be a game object. Or you can instantiate it, cast to RigidBody, then use the .gameObject accessor. Like this:
((RigidBody)Instantiate(theRigidbody)).gameObject
Second problem: start simple with the rotation. If it's not working, don't get fancy yet. Start with something like this (an instant rotation toward the target):
Vector3 targetDirection = target.transform.position - transform.position;
targetDirection.y = 0; // optional: don't look up
transform.forward = targetDirection;
If it works, then add small pieces of additional complexity until it does exactly what you want. And if you don't get things figured out, give me a shout (a comment) on Monday. I've written turret-aiming code (including a maximum rotation speed), and I don't think my boss would mind if I upload it.

Categories