unity2d move a game object towards a random position - unity3d

i have a satellite which i let spawn randomly in a different script by just using the method Satellite() and i want it move towards the bottom of the screen but not towards the middle but again a random position of the ground. the problem is that satellitedirection is always 0. also, if i somehow would manage to get the problem solved, wouldn´t every satellite on the screen move towards the same position?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SatelliteBehaviour : MonoBehaviour
{
[SerializeField] Rigidbody2D satelliteRB;
[SerializeField] Transform satelliteFirePoint;
[SerializeField] GameObject satellitePrefab;
float satellitedirection;
void Start()
{
}
void Update()
{
transform.Rotate(0,0,80*Time.deltaTime);
//satelliteRB.velocity = -transform.up * 5;
transform.position = Vector2.MoveTowards(transform.position, new Vector2(satellitedirection, -15), 1 * Time.deltaTime);
Debug.Log(satellitedirection);
}
public void Satellite()
{
Instantiate(satellitePrefab, new Vector2(Random.Range(-18,18),10), Quaternion.identity);
satellitedirection = Random.Range(-18, 18);
}
}

The Instantiate() method returns a game object but it is not assigned to anything. Assign a var and set its position and rotation.
GameObject satelliteObj = Instantiate(satellitePrefab, new Vector2(Random.Range(-18,18),10), Quaternion.identity);
// random rotation
satelliteObj.transform.rotation = Quaternion.Euler(new Vector2(Random.Range(-180, 180), Random.Range(-180, 180)));

Related

How do I rotate an object's parent without the child being moved along?

In my game on unity 2d I have spaceship and a planet. The planet is orbiting a star so I made a script that parents the planet to the player when I get within a range so the planet doesn't fly past or into the player. This script makes the player move with the planet so they land on it and fly around it easily.
Here is the script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ParentPlayer : MonoBehaviour
{
[SerializeField] GameObject Player;
private float Dist;
[SerializeField] float Threshold;
private CircleCollider2D ParentTrigger;
// Start is called before the first frame update
void Start()
{
ParentTrigger = GetComponents<CircleCollider2D>()[1];
ParentTrigger.isTrigger = true;
ParentTrigger.radius = Threshold / transform.localScale.x;
}
// Update is called once per frame
void Update()
{
}
private void OnTriggerEnter2D(Collider2D collider)
{
if(collider.gameObject == Player)
{
collider.gameObject.transform.SetParent(transform);
}
}
private void OnTriggerExit2D(Collider2D collider)
{
if(collider.gameObject == Player)
{
collider.gameObject.transform.SetParent(null);
}
}
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, Threshold);
}
}
The problem is that as the planet rotates it ends up moving the player that has been parented to it. How can I make the planet's rotation not affect the position and rotation of the player, but still make the planets position affect the position of the player?
This might not be what you're looking for but I'm going to add it reguardless. Given that the Child-object will follow the parent, I would suggest putting the planet and spaceship as a child of the empty gameobject. Then you could rotate the the planet object, and if planets are in movement, you could add the movement to the parent object.
How about instead of parenting the player, write a script to set its position to the planets + some offset, and then the rotation wouldn't be an issue. Alternatively, if the player doesn't rotate at all, add constraints to its Rigidbody. Maybe something like this:
player.transform.position = planet.transform.position + offset;
Hope that works!

Object won fall of the platform in Unity

So i made an ball(player) which moves forward on it's own with script. I want to make that ball act like a normal ball. when it riches the edge of platform it won't fall off. Basicaly it stops on the edge. Here's my image:
Here's my controller script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SwerveInputSystem : MonoBehaviour
{
private float _lastFrameFingerPositionX;
private float _moveFactorX;
public float MoveFactorX => _moveFactorX;
void Start(){
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
_lastFrameFingerPositionX = Input.mousePosition.x;
}
else if (Input.GetMouseButton(0))
{
_moveFactorX = Input.mousePosition.x - _lastFrameFingerPositionX;
_lastFrameFingerPositionX = Input.mousePosition.x;
}
else if (Input.GetMouseButtonUp(0))
{
_moveFactorX = 0f;
}
}
}
This is Second script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour{
private SwerveInputSystem _swerveInputSystem;
[SerializeField] private float swerveSpeed = 5f;
[SerializeField] private float maxSwerveAmount = 1f;
[SerializeField] private float verticalSpeed;
void Start(){
_swerveInputSystem = GetComponent<SwerveInputSystem>();
}
void Update(){
float swerveAmount = Time.deltaTime * swerveSpeed * _swerveInputSystem.MoveFactorX;
swerveAmount = Mathf.Clamp(swerveAmount, -maxSwerveAmount, maxSwerveAmount);
transform.Translate(swerveAmount, 0, 0);
float verticalDelta = verticalSpeed * Time.deltaTime;
transform.Translate(swerveAmount, verticalDelta, 0.1f);
}
}
EDITED: Adjusted the answer since we now have some source code.
You are positioning the player directly (using its transform) which will mess up the physics. The purpose of a rigidbody is to let Unity calculate forces, gravity, and so on for you. When you are using physics, and you want to move an object you have three main options:
Teleporting the object to a new position, ignoring colliders and forces like gravity. In this case use the rigidbody's position property.
_ourRigidbody.position = new Vector3(x, y, z);
Moving the object to the new position, similar to teleporting but the movement can be interrupted by other colliders. So, if there is a wall between the object and the new position, the movement will be halted at the wall. Use MovePosition().
_ourRigidbody.MovePosition(new Vector3(x, y, z));
Adding some force to the object and letting the physics engine calculate how the object is moved. There are several options like AddForce() and AddExplostionForce(), etc... see the Rigidbody component for more information.
_ourRigidbody.AddRelativeForce(new Vector3(x, y, z));
In your case you can simply remove the transsform.Translate() calls and instead add some force like this:
//transform.Translate(swerveAmount, 0, 0);
//transform.Translate(swerveAmount, verticalDelta, 0.1f);
Vector3 force = new Vector3(swerveAmount, verticalDelta, 0);
_ourRigidbody.AddForce(force);
We can get the _ourRigidbody variable in the Awake() or Start() method as normal. As you can see I like the Assert checks just to be safe, one day someone will remove the rigidbody by mistake, and then it is good to know about it...
private SwerveInputSystem _swerveInputSystem;
private Rigidbody _ourRigidbody;
void Start()
{
_swerveInputSystem = GetComponent<SwerveInputSystem>();
Assert.IsNotNull(_swerveInputSystem);
_ourRigidbody = GetComponent<Rigidbody>();
Assert.IsNotNull(_ourRigidbody);
}
One likely reason your Rigidbody is not being affected by gravity is due to having the field isKinematic checked to on. From the Rigidbody docs, when toggling on isKinematic,
Forces, collisions or joints will not affect the rigidbody anymore.
The rigidbody will be under full control of animation or script
control by changing transform.position
As gravity is a force and no forces act on the object when this setting is checked, your object will not fall when it is no longer on the platform. A simple solution is to uncheck this box.

Unity 3d Rigidbody moving but not child object

I have made a car scene in Unity. I have one Rigidbody (car) and its childgameobject. I made a script to move that childgameobject with sliders while Rigidbody is moving. The childgameobject moves fine with the slider but when my Rigidbody moves, the child GameObject remains in the same position and doesn't move with Rigidbody. Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ChildMove : MonoBehaviour
{
public Slider MySliderx;
public Slider MySlidery;
public Slider MySliderz;
public Transform Cam;
public float temp;
private float CamInitialY = 0f;
private float CamInitialX = 0f;
private float CamInitialZ = 0f;
// Use this for initialization
void Start () {
CamInitialY = Cam.transform.position.y;
CamInitialX = Cam.transform.position.x;
CamInitialZ = Cam.transform.position.z;
}
// Update is called once per frame
void Update () {
Cam.transform.position = new Vector3 (Cam.position.x, CamInitialY + MySliderx.value , Cam.position.z);
Cam.transform.position = new Vector3 (CamInitialX + MySlidery.value, Cam.position.y, Cam.position.z);
Cam.transform.position = new Vector3 (Cam.position.x, Cam.position.y, CamInitialZ + MySliderz.value);
}
}
Fixed by changing position to localposition.

How do I make a camera that points towards where the player is going and is back and up and pointed down?

it is a ball that actally rolls so I can't just put a child camera on with an offset and call it a day so instead I created this script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class camera : MonoBehaviour
{
public GameObject Player;
public Vector3 lastpos;
public Vector3 cameraxyz;
public Vector3 camerarotationxyz;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
Vector3 currentDirection = Player.transform.position - lastpos;
transform.rotation = Quaternion.LookRotation(currentDirection-camerarotationxyz);
transform.position = currentDirection + cameraxyz;
Vector3 lastPos = Player.transform.position;
}
}
and attached it to an empty game object made the game object a child of the ball and then made the camera a child of the empty game object
which half works the empty game object will all always rotate to have it's z axis aligned with the origin meaning the offset for the camera is wrong and it won't look at where the ball is going but will look towards the ball
this is how I set the hierarchy up (I put the script on the empty game object)
https://i.stack.imgur.com/sbiMt.png
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class camera : MonoBehaviour
{
public GameObject Player;
public Vector3 lastPos;
public Vector3 cameraxyz;
public Vector3 camerarotationxyz;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
Vector3 currentDirection = Player.transform.position - lastPos;
transform.rotation = Quaternion.LookRotation(currentDirection - new Vector3(0,currentDirection.y,0));
Vector3 newPosition = currentDirection + cameraxyz;
transform.position = newPosition;
lastPos = Player.transform.position;
transform.position = Player.transform.position;
}
}
taking the Vector3 off of lastPos and capitalizing mistakes leads to a gameobject with an incorrect offset and rotation to stop it traking the y axis (as I can change which whay is up and change the y to be parrallel to gravity using an external script) I did (currentDirection - new Vector3(0,currentDirection.y,0) the new Vector3 is needed and so are the zeros as a float nor int cannot be use to subtract from a Vector3 then I did transform.position = Player.transform.position; so that the empty game object is correctly put on the ball then to get the camera to move with the correct offset I made the camera a child of the emptygameobject

Rotating a child gameobject relative to immediate parent

Hi everybody, I'm trying to rotate a child game object relative to another child game object. For example, as shown in this heirarchy below, I'm trying to rotate PA_DroneBladeLeft (and PA_DroneBladeRight) with respect to their immediate parents PA_DroneWingLeft (and PA_DroneWingRight) respectively. I want these blades to spin in place. Instead I'm getting them to spin globally in the y-direction relative to the main parent (Air Drone). I would think that the line in Update method that I commented out should have worked, and it did but it still rotated relative to Air Drone and not in place. The second line, RotateAround method I've tried to create an empty game object called Left Pivot and put it approximately in the center of the left wing and have the left blade rotate around that, but it was no use.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LeftBladeRotation : MonoBehaviour
{
GameObject leftBlade;
private float speed;
private float angle;
GameObject leftPivot;
// Start is called before the first frame update
void Start()
{
speed = 10f;
leftBlade = transform.Find("PA_DroneBladeLeft").gameObject;
angle = 0f;
leftPivot = GameObject.FindGameObjectWithTag("Air Drone").transform.Find("PA_Drone").transform.Find("PA_DroneWingLeft").transform.Find("Left Pivot").gameObject;
}
// Update is called once per frame
void Update()
{
angle += speed * Time.deltaTime;
Quaternion rotation = Quaternion.Euler(new Vector3(0f, angle, 0f));
//leftBlade.transform.localRotation = rotation;
leftBlade.transform.RotateAround(leftPivot.transform.localPosition, Vector3.up, angle);
}
}
This is your script with some little changes. It actually works when I attached it on the blade gameObject.
using UnityEngine;
public class BladeRotate : MonoBehaviour
{
private float _speed;
private float _angle;
private void Start()
{
_speed = 400f;
_angle = 0f;
}
private void Update()
{
_angle += _speed * Time.deltaTime;
var rotation = Quaternion.Euler(new Vector3(0f, _angle, 0f));
transform.localRotation = rotation;
}
}
The second line does not work because you rotate the blade around global y-axis by Vector3.up
Here is an alternative. Attach the following script on your blades.
using UnityEngine;
public class BladeRotate : MonoBehaviour
{
[SerializeField] private int speed = 400;
private Transform _transform;
private void Start()
{
_transform = transform;
}
private void Update()
{
transform.RotateAround(_transform.position, _transform.up, speed * Time.deltaTime);
}
}