Reputation: 11321
The code that rotate the turret is kind simple:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Rotateturret : MonoBehaviour
{
public Transform target;
public Transform partToRotate;
public float turnSpeed = 10f;
private void Update()
{
transform.LookAt(target);
}
}
The target in this case is rotatingaround the turret in fixed speed but changing the height randomly.
If this script RotateTurret if I attach it to the Turret child part it will rotate and will look at the target. Like doing LookAt. This is a screenshot of the Turret part:
And if I attach the script to the Pylon part it will rotate slowly and will always stay behind the target it will not rotate fast enough.
Screenshot of the Pylon part:
My problems are: What part of the turret should I rotate ? The logic say the Pylon I think.
Second is how should I calculate the speed the turret should rotate ? Does it always should facing perfect to the target ? Or sometimes if the target is moving in random speeds the turret will not facing it all the time 100% ? What is the logic in this case ? Just using LookAt is not enough. And I'm not using physics yet that's another problem I guess. If both turret and target will use physics but for now not sure how to do the turret logic (Or should I call it AI).
For testing I tried this script too:
public class Rotateturret : MonoBehaviour
{
public Transform target;
public Transform partToRotate;
public float turnSpeed = 10f;
private void Update()
{
Debug.DrawRay(transform.position, transform.forward, Color.green, 1000);
Vector3 dir = target.position - transform.position;
Quaternion lookRotation = Quaternion.LookRotation(dir);
Vector3 rotation = Quaternion.Lerp(partToRotate.rotation, lookRotation, Time.deltaTime * turnSpeed).eulerAngles;
partToRotate.rotation = Quaternion.Euler(0f, rotation.y, 0f);
}
}
And again if I will rotate the Turret it will be more accurate but if the pylon it will be behind the target. And who said the speed of the rotating of the turret should be 10 and 20 or 50 or 1 ? There is no much logic in this script either I guess.
Another thing is that in the future I will want also to rotate the Gun to shoot bullets. So the rate fire and when to start firing that's another problem maybe that will be another question, But I guess the firing shooting bullets is also relevant to the turret rotating logic.
Upvotes: 0
Views: 774
Reputation: 5035
Firstly, there is a LookRotation overload that takes the axis as a second parameter, so if you try
Quaternion lookRotation = Quaternion.LookRotation(dir,Vector3.up);
the rotation will always be around a vertical axis. This way you can split up motion into seperate axis as you would with a mechanical device (i.e. the pylon only rotates around a vertical axis)
As for the second part, i.e. how to make the turret hit the target, there's several approaches you can take:
You could, for example take the distance between the turret and the target, divide bullet velocity by target velocity, and take target.transform.forward multiplied by that ratio and the distance (this is from head, but you get the idea).
A bit more interesting alternative is to take the opportunity to learn about PID controllers, turrets are a fantastic example of how much can you do with a very simple controller.
PID stands for Proportional, Integral and Deriviative, and you compute your actuator output (i.e. force that drives your rotation) based on those three ways of looking at values. In the most simplitied form it works like that: Proportional is your direct delta - how much of an angle away from your target angle you are (or from the target forward point). Than you average out that parameter (i.e. lerp the current value towards the target or using moving average) by a signifficant amount, this is your integral part - it will follow the target in a much slower way. Now if you subtract your averaged (integrated) value from your current (propoprtional) value, you get something that represents your change, this can be used as a deiviative component. Now this last part is what makes the turrent react to when the target is changing trajectory, you can make the output overshoot the change, or tune it in multiple other ways
Upvotes: 0
Reputation: 2303
Firstly, note that from your screenshot, the Pylon
gameobject's forward direction
(blue arrow) is perpendicular to the turret barrel's direction. Thus, attaching your script on that gameobject will not produce your desired behaviour.
When it comes to the implementation of a turret's movement, it depends greatly on the context of your game.
For example, if the turret is to be used in a Tower Defence game where it should never miss, then typically the turret's rotation and shooting animation should just be an effect. Your actual damage dealing to the target will be done via script directly (e.g searching for viable target in range and sending an onShoot event). In this case, a transform.lookAt()
is good enough, as it produces a reasonable visual effect.
However, if your turret is to be used in a First Player Shooter game, expect then that it's rotation will be controlled by the player (either via transform or rigidbody physics). Whether or not the turret should deal damage to the enemy depends on whether the projectile (simulated via physics with rigidbody and collider) hits the enemy or not. In this case, you have to limit your turret's maximum rotation speed. How much the threshold is depends on how realistic you want it to be.
Upvotes: 1