As the title says, I have a scene with three objects, a cube, a sphere, and a cylinder-like you can see in the image below.
What I'm trying to achieve is that when I press the "Rotate" button, the three objects rotate in an anti-clockwise direction, so the cylinder goes where the cube was, the cube goes where the sphere was, and the sphere goes where the cylinder was. If I click the button again, they rotate once again and so on. So far, I managed to make them rotate around an empty object at the center of the "triangle" they form with their initial position.
This is what happens when I first click the "Rotate" button:
As you can see, the object rotates, but they don't keep the same coordinate of the object that was previously in that position, so I was thinking of having them exchange coordinates. How can I achieve that or making them rotate how I want to?
Here is the code I wrote so far:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class RotateObject : MonoBehaviour {
//rotating objects
[SerializeField]
private GameObject cube;
[SerializeField]
private GameObject sphere;
[SerializeField]
private GameObject cylinder;
private Renderer cubeRenderer;
private Renderer sphereRenderer;
private Renderer cylinderRenderer;
//rotation target
public GameObject target;
private void Start() {
cubeRenderer = cube.GetComponent<Renderer>();
sphereRenderer = sphere.GetComponent<Renderer>();
cylinderRenderer = cylinder.GetComponent<Renderer>();
gameObject.GetComponent<Button>().onClick.AddListener(Rotate);
}
void Rotate() {
//rotate objects by 120 degrees
cube.transform.RotateAround(target.transform.position, Vector3.up, -120);
sphere.transform.RotateAround(target.transform.position, Vector3.up, -120);
cylinder.transform.RotateAround(target.transform.position, Vector3.up, -120);
}
}
Thanks in advance for helping me!
The easiest way to make an object(s) rotate around a point is to have it/them as a child of the point then rotate the point itself.
Object Hierarchy
Rotator Script to be put on the parent object:
public class RotateObjects : MonoBehaviour
{
[SerializeField] Button rotateButton;
// Start is called before the first frame update
void Start()
{
rotateButton.onClick.RemoveAllListeners();
rotateButton.onClick.AddListener(RotateClockwise);
}
void RotateClockwise()
{
float newRotation = (360 / transform.childCount);
transform.Rotate(new Vector3(0, newRotation, 0));
}
}
You are rotating around an object. Like the earth rotates around the sun; that means it will change its position. Use
transform.rotation = new Quaternion(rotx, roty, rotz, rotw);
or
transform.Rotate(rotx, roty, rotz);
Instead of rotating about a point rotate the shape, it's self.
Related
I am trying to build a flappy bird like game and I am trying to spawn enemy birds and gold coins so I have written the C# code and the made the prefabs, but when I run the bird and the coins are not respawning.
This is the respawn code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnPlayer : MonoBehaviour
{
public GameObject GameObjectToSpawn;
private GameObject Clone;
public float timeToSpawn = 4f;
public float FirstSpawn = 10f;
// Update is called once per frame
void Update()
{
FirstSpawn -= Time.deltaTime;
if (FirstSpawn <= 0f)
{
Clone = Instantiate(GameObjectToSpawn, gameObject.transform.localPosition, Quaternion.identity) as GameObject;
FirstSpawn = timeToSpawn;
}
}
}
screenshot of unity:
This where i am respawning the first enemy bird:
From your second screenshot it seems to be spawned but way off the screen! You can still see the tiny little island in the bottom left corner.
You thought seems to be that you have to spawn it in the Canvas pixel space using the spawn point's localPosition. But this is not the case since Instantiate places it into the scene root (without any parent) with absolute world-space position into the scene.
You should rather actually place the spawn point to the absolute world position where the spawn should happen and rather use
Clone = Instantiate(GameObjectToSpawn, transform.position, Quaternion.identity);
Btw no need for the as GameObject since Instantiate already returns the type of the given prefab.
I am using unity 2018.3.5f1 so a few solutions to this problem don't work.
Starting from the Roll-A-Ball demo project, I want to extend the camera script to follow the player, but also keeping track of the direction of movement. Ex: If the ball starts moving to the side, I need the camera to rotate around the player's axis to position behind him, and then start following him.
I have tried making the camera a child to the ball i'm trying to control and i've tried making a script but it won't follow the ball correctly it keeps rotating the camera as well as the ball (i'm using this bit of code and trying to modify it as it's the only one that works)
here is the code I have at the moment:
using UnityEngine;
using System.Collections;
public class CompleteCameraController : MonoBehaviour
{
public GameObject player; //Public variable to store a reference to the player game object
private Vector3 offset; //Private variable to store the offset distance between the player and camera
// Use this for initialization
void Start()
{
//Calculate and store the offset value by getting the distance between the player's position and camera's position.
offset = transform.position - player.transform.position;
}
// LateUpdate is called after Update each frame
void LateUpdate()
{
// Set the position of the camera's transform to be the same as the player's, but offset by the calculated offset distance.
transform.position = player.transform.position + offset;
}
}
I understand why it is rotating but no reasearch is helping me find out how to lock the camera so it is looking behind the ball at all times
Have you tried adding some restraints to your camera? If it is only supposed to turn to follow the ball, you can freeze the position of 2 axes (x and z), and only let the camera rotate around the y axis of the ball.
You can play around with the restraints on the Inspector, or use GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeRotationX; in the camera script.
(EDIT) Sorry, this is how you would do it if the gameObject has a rigidbody, but the idea is the same if it doesn't have one.
When you're setting the position or rotation of the camera, think about which components of the position/rotation you actually want to change (x,y,z).
Use offset = new Vector3 (offset.x, offset.y, offset.z)and replace anything that shouldn't change with a constant.
Also, when you made the Camera the child of the ball, you could have set it so that every frame, the Camera updates in such a way that it won't roll with the ball. You could do this by putting code in the update method of the camera that sets the component x, y, or z equal to some constant. Whatever axis the ground plane is on is probably the correct choice.
If you want the same camera angle that the camera should follow while following the ball (similar to Temple Run), then try the below code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class CompleteCameraController : MonoBehaviour
{
public Transform Player;
public float distanceFromObject = 3f;
void Update()
{
Vector3 lookOnObject = Player.position - transform.position;
lookOnObject = Player.position - transform.position;
transform.forward = lookOnObject.normalized;
Vector3 playerLastPosition;
playerLastPosition = Player.position - lookOnObject.normalized * distanceFromObject;
playerLastPosition.y = Player.position.y + distanceFromObject / 2;
transform.position = playerLastPosition;
}
When the ball moves left or right, the camera will follow the same angle as the ball moves towards.
Screenshot of the bullets when firing :
The bullets are stay still and they are standing.
This screenshot show the Fire Point inspector position rotation scaling :
And a screenshot of the bullet prefab settings :
Last screenshot show the Shooting gameobject inspector settings :
And the script Shooting :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooting : MonoBehaviour
{
[SerializeField]
private Transform[] firePoints;
[SerializeField]
private Rigidbody projectilePrefab;
[SerializeField]
private float launchForce = 700f;
public void Update()
{
if (Input.GetButtonDown("Fire1"))
{
LaunchProjectile();
}
}
private void LaunchProjectile()
{
foreach (var firePoint in firePoints)
{
var projectileInstance = Instantiate(
projectilePrefab,
firePoint.position,
firePoint.rotation);
projectileInstance.AddForce(firePoint.forward * launchForce);
}
}
}
And how can I make that it will not leave a trail of bullets behind ?
For the rotation you want to set the projectile to the same rotation as the weapon.
transform.rotation = Quaternion.Euler(gunAngle)
the projectile should be another gameObject instead of rigidBody.
you'll also need a destruction script on them or they'll never disappear and you will have a million projectiles in play lagging the game. destroy gameObject by collision and time.
Regarding the trail of bullets, you should consider adding a cooldown to the LaunchProjectile method. Right now every time update is called it calls LaunchProjectile if the fire button is down, even if it called LaunchProjectile the update before (at 60 ups(?) you'd have to be pretty fast off of the fire button to only shoot one projectile).
Hello I am trying to make my platform rotate 90 degrees when my player collide with the button. I have no clue atm and can only make my platform go around simentanously. I want it to happen seperatly cause each platform has its seperate button. I am using unity and csharp.
picture of map
https://gyazo.com/0efce1c230d703b793cf7cab0384ee4e
orange = button
i wanna move the correspondent platform
attach a Collider2D to GameObject make it IsTrigger and attach a script to it on code
void OnTriggerEnter2D(Collider2D col)
{
if(col.gameObject.tag=="Player")
platformObject.transform.rotation.x=90; //could be Y too
}
something like this would do.
Edit
https://docs.unity3d.com/ScriptReference/Quaternion.Lerp.html
using UnityEngine;
public class Example : MonoBehaviour
{
// Interpolates rotation between the rotations
// of from and to.
// (Choose from and to not to be the same as
// the object you attach this script to)
Transform from;
Transform to;
float speed = 0.1f;
void Update()
{
transform.rotation = Quaternion.Lerp(from.rotation, to.rotation, Time.time * speed);
}
}
I have been working on getting a camera to follow my player when he moves with 3rd person controller.
At the moment the camera does follow him but the view remains looking forward, so if I was to move left and right the camera sits still instead of rotating to face the same direction as my character.
The code I currently have is:
using UnityEngine;
using System.Collections;
public class CameraController : MonoBehaviour
{
public GameObject player;
private Vector3 offset;
void Start ()
{
offset = transform.position - player.transform.position;
}
void LateUpdate ()
{
transform.position = player.transform.position + offset;
}
}
Anyone know a solution to make my camera rotate with the charater?
You have three option for getting this done.
Make the camera as a child of your 3rd person in game object hierarchy.
Using scripts align its forward vector to the person's forward vector.
transform.forward = player.transform.forward;
Using scripts make the camera to LookAt the 3rd person.
transform.LookAt(player);