I have a turret placed as a game-object ,i have set the target as enemy in inspector,but somehow the turrets just point towards my enemy but are not continuously rotating on z axis.what is the problem,any help thanx...!!
Here is my code
using UnityEngine;
using System.Collections;
public class TurretScript: MonoBehaviour
{
public Transform target;
void Update()
{
Vector3 tarPos = new Vector3(target.position.x, target.position.y, 10);
Vector3 lookPos = Camera.main.ScreenToWorldPoint(tarPos);
lookPos = lookPos - transform.position;
float angle = Mathf.Atan2(lookPos.y, lookPos.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
}
}
Easiest way to achieve this? Cheat! Something like this:
public class TurretScript: MonoBehaviour
{
//values that will be set in the Inspector
public Transform Target;
public float RotationSpeed;
void Update()
{
var direction = Target.transform.position - transform.position;
// Set Y the same to make the rotations turret-like:
direction.y = transform.position.y;
var rot = Quaternion.LookRotation(direction, Vector3.up);
transform.rotation = Quaternion.RotateTowards(
transform.rotation,
rot,
RotationSpeed * Time.deltaTime);
}
}
You can also use Transform.LookAt() from the Documentation
I find this to be the simplest approach without the headache of computing rotations.
Related
I'm working on a little 2d game where you control a planet to dodge incoming asteroids. I'm implementing gravity in the following manner:
public class Gravity : MonoBehaviour
{
Rigidbody2D rb;
Vector2 lookDirection;
float lookAngle;
[Header ("Gravity")]
// Distance where gravity works
[Range(0.0f, 1000.0f)]
public float maxGravDist = 150.0f;
// Gravity force
[Range(0.0f, 1000.0f)]
public float maxGravity = 150.0f;
// Your planet
public GameObject planet;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
// Distance to the planet
float dist = Vector3.Distance(planet.transform.position, transform.position);
// Gravity
Vector3 v = planet.transform.position - transform.position;
rb.AddForce(v.normalized * (1.0f - dist / maxGravDist) * maxGravity);
// Rotating to the planet
lookDirection = planet.transform.position - transform.position;
lookAngle = Mathf.Atan2(lookDirection.y, lookDirection.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, lookAngle);
}
}
The problem is that the asteroids are attracted to the initial spawn point of the planet (0,0), it doesn't update in real time with the movement of the planet. So if I move the planet to the corner of the screen, the asteroids are still attracted to the centre of it.
Is there a way to solve this?
Thank you very much and excuse any flagrant errors!
There are 2 ways to get to an object with speed:
get the object to the player and in each update just use the planet.transform.position
using look at first to rotate to the plant and then using vector3.forword as the direction of the movement.
The first solution doesn't work for you so you might want to try the second one.
any way, if your lookAt part doesn't work too you can use
Vector3 dir = target.position - transform.position;
float angle = Mathf.Atan2(dir.y,dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
or
Vector3 targetPos = target.transform.position;
Vector3 targetPosFlattened = new Vector3(targetPos.x, targetPos.y, 0);
transform.LookAt(targetPosFlattened);
I am making the enemy character to follow the player character.
In the FixedUpdate method the enemy character move toward the player character,
then in the Update method character rotates to the player character.
However, with this script, somehow enemy character is just nudging and gets stuck.
Where is the mistake, what's wrong???
public class enemy : MonoBehaviour
{
GameObject tObj;
private Vector3 latestPos;
public string targetObjectName;
public float speed = (float)1.0;
void Start()
{
tObj = GameObject.Find("player");
latestPos = transform.position;
}
void Update()
{
Vector3 diff = transform.position - latestPos;
latestPos = transform.position;
if (diff.magnitude > 0.01f)
{
transform.rotation = Quaternion.LookRotation(diff);
}
}
void FixedUpdate(){
Vector3 dir = (tObj.transform.position - this.transform.position).normalized;
float vx = dir.x * speed;
float vz = dir.z * speed;
this.transform.Translate((float)(vx / 50.0),0,(float)(vz / 50.0));
}
}
Use Package Manager "Standard Assets", Inside Unity put two FPSController one should be Player and the second can be Enemy.
I know this does not answers your question but its a faster way to ad Enemy.
AI Settings
Just remove the camera, Audio Source and First Person Controller Script as in image.
The Code for AI:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowAI : MonoBehaviour
{
public CharacterController _controller;
public Transform target;
public GameObject Player;
[SerializeField]
float _moveSpeed = 2.0f;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update() {
Vector3 direction = target.position - transform.position;
direction = direction.normalized;
Vector3 velocity = direction * _moveSpeed;
_controller.Move(velocity * Time.deltaTime);
Vector3 lookVector = Player.transform.position - transform.position;
lookVector.y = transform.position.y;
Quaternion rot = Quaternion.LookRotation(lookVector);
transform.rotation = Quaternion.Slerp(transform.rotation, rot, 1);
}
}
I am making a top down game on Unity, so I am using the x and z axis as my plane. I have my character rotated x 90, y 0, z 0 so that it is flat on the plane. As soon as I hit play the character is rotated vertical?! I think it has something to do with my script to face the mouse position.
What it should look like:
When I hit play:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public static float moveSpeed = 10f;
private Rigidbody rb;
private Vector3 moveInput;
private Vector3 moveVelocity;
// Update is called once per frame
void Start()
{
rb = GetComponent<Rigidbody>();
mainCamera = FindObjectOfType<Camera>();
}
void Update()
{
// Setting up movement along x and z axis. (Top Down Shooter)
moveInput = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
moveVelocity = moveInput * moveSpeed;
//Make character look at mouse.
var dir = Input.mousePosition - Camera.main.WorldToScreenPoint(transform.position);
var angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.up);
}
void FixedUpdate()
{
// Allows character to move.
rb.velocity = moveVelocity;
}
}
Figured it out: I am answering my own question to help others.
Vector3 difference = Input.mousePosition - Camera.main.WorldToScreenPoint(transform.position);
float rotZ = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(90f, 0f, rotZ -90);
This does EXACTLY what I wanted!
i need your help please.
i want an object to rotate in Y axis (space.self) toward the player position.
i have already tried this code, it works but i think there is a bug in it because the object keep changing position slowly.
public Transform _Playertrs;
public float RotationSpeed = 10f;
private Quaternion _LookRotation;
private Vector3 _direction;
private bool Patroling = true;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
_direction = (_Playertrs.position - transform.position).normalized;
_LookRotation = Quaternion.LookRotation(_direction);
transform.rotation = Quaternion.Slerp(transform.rotation, _LookRotation, Time.deltaTime * RotationSpeed);
}
thank you guys for your answers, the rotation is working perfectly now, but the problem is the object keep moving from its position even that i don't have any movement code, watch the video to understand pls
https://www.youtube.com/watch?v=Gys5xYQ5psw&feature=youtu.be
If you want it to be instantaneous, replace
transform.rotation = Quaternion.Slerp(transform.rotation, _LookRotation, Time.deltaTime * RotationSpeed);
by
transform.rotation = _LookRotation;
The Slerp function gives an intermediate point between the to rotation to make a smooth effect.
Here, this is taken from the Unity Quaternion.LookRotation() official documentation, you can just simply apply the Quaternion that you have _LookRotation and apply it to your desired transform.rotation as such transform.rotation = _LookRotation;
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
public Transform target;
void Update() {
Vector3 relativePos = target.position - transform.position;
Quaternion rotation = Quaternion.LookRotation(relativePos);
transform.rotation = rotation;
}
}
I'm struggling with this for quit some time now. I have GameObject, being a sphere, which is my player on a 3d Terrain. I have a Camera which is always on a fixed distance from the player, follows it where it goes with below script:
public GameObject player;
private Vector3 offset;
// Use this for initialization
void Start () {
offset = transform.position - player.transform.position;
}
void LateUpdate () {
transform.position = player.transform.position + offset;
}
So far so good. However what I actually want is that the camera rotates with the player, so it always looks into the direction where the sphere is moving, but always stays behind the player at the same fixed distance, so that the player is always visible in the camera view.
There are a lot of scripts available, but the problem with the onces I've seen so far is that the camera indeed rotate with the player, but because the player actually is a rolling sphere the camera view is rolling and turning as well.
The best script I found so far is below, but this one has the same problem as the other onces, the camera rolls with the player.
public Transform target;
public float distance = 3.0f;
public float height = 3.0f;
public float damping = 5.0f;
public bool smoothRotation = true;
public bool followBehind = true;
public float rotationDamping = 10.0f;
void Update () {
Vector3 wantedPosition;
if(followBehind)
wantedPosition = target.TransformPoint(0, height, -distance);
else
wantedPosition = target.TransformPoint(0, height, distance);
transform.position = Vector3.Lerp (transform.position, wantedPosition, Time.deltaTime * damping);
if (smoothRotation) {
Quaternion wantedRotation = Quaternion.LookRotation(target.position - transform.position, target.up);
//Quaternion ownRotation = Quaternion.RotateTowards;
transform.rotation = Quaternion.Slerp (transform.rotation, wantedRotation, Time.deltaTime * rotationDamping);
}
else transform.LookAt (target, target.up);
}
Can anyone help me with this please?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraFollow : MonoBehaviour {
public GameObject player;
public float cameraDistance = 10.0f;
// Use this for initialization
void Start () {
}
void LateUpdate ()
{
transform.position = player.transform.position - player.transform.forward * cameraDistance;
transform.LookAt (player.transform.position);
transform.position = new Vector3 (transform.position.x, transform.position.y + 5, transform.position.z);
}
}
My solution (based on #brennon-provencher answer) with smoothness and auto offset:
public class CameraFollow : MonoBehaviour
{
public GameObject target;
public float speed = 5;
Vector3 offset;
void Start()
{
offset = target.transform.position - transform.position;
}
void LateUpdate()
{
// Look
var newRotation = Quaternion.LookRotation(target.transform.position - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, speed * Time.deltaTime);
// Move
Vector3 newPosition = target.transform.position - target.transform.forward * offset.z - target.transform.up * offset.y;
transform.position = Vector3.Slerp(transform.position, newPosition, Time.deltaTime * speed);
}
}
You need to move your camera position based on sphere movement direction -
public GameObject player;
private Vector3 offset;
float distance;
Vector3 playerPrevPos, playerMoveDir;
// Use this for initialization
void Start () {
offset = transform.position - player.transform.position;
distance = offset.magnitude;
playerPrevPos = player.transform.position;
}
void LateUpdate () {
playerMoveDir = player.transform.position - playerPrevPos;
playerMoveDir.normalize();
transform.position = player.transform.position - playerMoveDir * distance;
transform.LookAt(player.transform.position);
playerPrevPos = player.transform.position;
}
Edit 2: To fix flickering camera, try this -
void LateUpdate () {
playerMoveDir = player.transform.position - playerPrevPos;
if (playerMoveDir != Vector3.zero)
{
playerMoveDir.normalize();
transform.position = player.transform.position - playerMoveDir * distance;
transform.position.y += 5f; // required height
transform.LookAt(player.transform.position);
playerPrevPos = player.transform.position;
}
}