- Home /
FPS Tutorial 3 : Robot rockets spawning below mesh
Hello,
I've followed the steps in the FPS tutorial 3, and for some reason after the 3rd or 4th rocket that the robot fires the rockets begin to fire underneath the level mesh. What am I doing wrong? Thank you!
Post your codes, explain the situation of your component. Even though you are following the tutorial, you probably did something wrong (or that would work obviously) but like this...are you applying the force to the spawn object for example?
my guess is you don't have the gun_spawn object a child of the robot. you need to take the gun_spawn object and drag it over the robot then drop. It should now be attached to it.
Now when you fire it should spawn relative to it's parent but if you don't have it parented to the robot it'll be wonky.
I am posting the scripts and situation in another answer to this question.
When the robot fires its rockets, it also sometimes kills itself because the rockets it fires are somehow colliding with the robot, when it shouldn't since the rocket launcher script has an ignore collision code written in it
If it makes it easier, I will post a YouTube video so you can see what is going on
Answer by Unity_Mike2012 · Aug 20, 2012 at 11:55 AM
This is the Rocket Launcher script I am using var projectile : Rigidbody; var initialSpeed = 20.0; var reloadTime = 0.5; var ammoCount = 20; private var lastShot = -10.0;
function Fire () { // Did the time exceed the reload time? if (Time.time > reloadTime + lastShot && ammoCount > 0) { // create a new projectile, use the same position and rotation as the Launcher. var instantiatedProjectile : Rigidbody = Instantiate (projectile, transform.position, transform.rotation); // Give it an initial forward velocity. The direction is along the z-axis of the missile launcher's transform. instantiatedProjectile.velocity = transform.TransformDirection(Vector3 (0, 0, initialSpeed));
// Ignore collisions between the missile and the character controller Physics.IgnoreCollision(instantiatedProjectile.collider, transform.root.collider); lastShot = Time.time; ammoCount--; } }
I have this attached to an empty game object I named "AI rocket spawn" and it is a child of the robot game object. I then moved the "AI rocket spawn" game object forward on the z axis. I have checked the local transform gizmos and everything is lining up fine. It is lined up on all three axis so that it should properly fire in fron of the robot when he plays the "shoot" animation. It works sometimes, then, as I said above, after a few shots all the rockets start firing from way below the level mesh for some reason. This was also happening to my player's rocket launcher until I deleted the player and created it again step by step according to the tutorial. Another thing I noticed was that when I hit the jump button sometimes the player will jump straight up on the Y axis and keep going up and never stop, it won't come down, it just keeps going up until I get an error message on the transform panel saying "Due to floating-precision limitations, it is recommended to keep the global coordinates within a short range of the game object" or something to that extent. I've tried re-creating a robot, ai rocket spawn game object, and attaching all the scripts as directed in the tutorial and for some reason the rockets of the robot keep firing all screwy after a few shots. It fires normal then, starts firing from below the level mesh. Here are the other scripts I am using that came with the FPS Tutorial zip file.
AI Script var speed = 3.0; var rotationSpeed = 5.0; var shootRange = 15.0; var attackRange = 30.0; var shootAngle = 4.0; var dontComeCloserRange = 5.0; var delayShootTime = 0.35; var pickNextWaypointDistance = 2.0; var target : Transform;
private var lastShot = -10.0;
// Make sure there is always a character controller @script RequireComponent (CharacterController)
function Start () { // Auto setup player as target through tags if (target == null && GameObject.FindWithTag("Player")) target = GameObject.FindWithTag("Player").transform;
Patrol(); }
function Patrol () { var curWayPoint = AutoWayPoint.FindClosest(transform.position); while (true) { var waypointPosition = curWayPoint.transform.position; // Are we close to a waypoint? -> pick the next one! if (Vector3.Distance(waypointPosition, transform.position) < pickNextWaypointDistance) curWayPoint = PickNextWaypoint (curWayPoint);
// Attack the player and wait until // - player is killed // - player is out of sight if (CanSeeTarget ()) yield StartCoroutine("AttackPlayer"); // Move towards our target MoveTowards(waypointPosition); yield; } }
function CanSeeTarget () : boolean { if (Vector3.Distance(transform.position, target.position) > attackRange) return false; var hit : RaycastHit; if (Physics.Linecast (transform.position, target.position, hit)) return hit.transform == target;
return false; }
function Shoot () { // Start shoot animation animation.CrossFade("shoot", 0.3);
// Wait until half the animation has played yield WaitForSeconds(delayShootTime); // Fire gun BroadcastMessage("Fire"); // Wait for the rest of the animation to finish yield WaitForSeconds(animation["shoot"].length - delayShootTime); }
function AttackPlayer () { var lastVisiblePlayerPosition = target.position; while (true) { if (CanSeeTarget ()) { // Target is dead - stop hunting if (target == null) return;
// Target is too far away - give up var distance = Vector3.Distance(transform.position, target.position); if (distance > shootRange * 3) return; lastVisiblePlayerPosition = target.position; if (distance > dontComeCloserRange) MoveTowards (lastVisiblePlayerPosition); else RotateTowards(lastVisiblePlayerPosition);
var forward = transform.TransformDirection(Vector3.forward); var targetDirection = lastVisiblePlayerPosition - transform.position; targetDirection.y = 0;
var angle = Vector3.Angle(targetDirection, forward);
// Start shooting if close and play is in sight if (distance < shootRange && angle < shootAngle) yield StartCoroutine("Shoot"); } else { yield StartCoroutine("SearchPlayer", lastVisiblePlayerPosition); // Player not visible anymore - stop attacking if (!CanSeeTarget ()) return; }
yield; } }
function SearchPlayer (position : Vector3) { // Run towards the player but after 3 seconds timeout and go back to Patroling var timeout = 3.0; while (timeout > 0.0) { MoveTowards(position);
// We found the player if (CanSeeTarget ()) return;
timeout -= Time.deltaTime; yield; } }
function RotateTowards (position : Vector3) { SendMessage("SetSpeed", 0.0); var direction = position - transform.position; direction.y = 0; if (direction.magnitude < 0.1) return; // Rotate towards the target transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime); transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0); }
function MoveTowards (position : Vector3) { var direction = position - transform.position; direction.y = 0; if (direction.magnitude < 0.5) { SendMessage("SetSpeed", 0.0); return; } // Rotate towards the target transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime); transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
// Modify speed so we slow down when we are not facing the target var forward = transform.TransformDirection(Vector3.forward); var speedModifier = Vector3.Dot(forward, direction.normalized); speedModifier = Mathf.Clamp01(speedModifier);
// Move the character direction = forward speed speedModifier; GetComponent (CharacterController).SimpleMove(direction); SendMessage("SetSpeed", speed * speedModifier, SendMessageOptions.DontRequireReceiver); }
function PickNextWaypoint (currentWaypoint : AutoWayPoint) { // We want to find the waypoint where the character has to turn the least
// The direction in which we are walking var forward = transform.TransformDirection(Vector3.forward);
// The closer two vectors, the larger the dot product will be. var best = currentWaypoint; var bestDot = -10.0; for (var cur : AutoWayPoint in currentWaypoint.connected) { var direction = Vector3.Normalize(cur.transform.position - transform.position); var dot = Vector3.Dot(direction, forward); if (dot > bestDot && cur != currentWaypoint) { bestDot = dot; best = cur; } } return best; }
AI Animation Script var minimumRunSpeed = 1.0;
function Start () { // Set all animations to loop animation.wrapMode = WrapMode.Loop;
// Except our action animations, Dont loop those animation["shoot"].wrapMode = WrapMode.Once; // Put idle and run in a lower layer. They will only animate if our action animations are not playing animation["idle"].layer = -1; animation["walk"].layer = -1; animation["run"].layer = -1; animation.Stop(); }
function SetSpeed (speed : float) { if (speed > minimumRunSpeed) animation.CrossFade("run"); else animation.CrossFade("idle"); }
Rocket Script // The reference to the explosion prefab var explosion : GameObject; var timeOut = 3.0;
// Kill the rocket after a while automatically function Start () { Invoke("Kill", timeOut); }
function OnCollisionEnter (collision : Collision) { // Instantiate explosion at the impact point and rotate the explosion // so that the y-axis faces along the surface normal var contact : ContactPoint = collision.contacts[0]; var rotation = Quaternion.FromToRotation(Vector3.up, contact.normal); Instantiate (explosion, contact.point, rotation); // And kill our selves Kill ();
}
function Kill () { // Stop emitting particles in any children var emitter : ParticleEmitter= GetComponentInChildren(ParticleEmitter); if (emitter) emitter.emit = false;
// Detach children - We do this to detach the trail rendererer which should be set up to auto destruct transform.DetachChildren(); // Destroy the projectile Destroy(gameObject); }
@script RequireComponent (Rigidbody)
AutoWayPoint Script static var waypoints = Array(); var connected = Array(); static var kLineOfSightCapsuleRadius = 0.25;
static function FindClosest (pos : Vector3) : AutoWayPoint { // The closer two vectors, the larger the dot product will be. var closest : AutoWayPoint; var closestDistance = 100000.0; for (var cur : AutoWayPoint in waypoints) { var distance = Vector3.Distance(cur.transform.position, pos); if (distance < closestDistance) { closestDistance = distance; closest = cur; } }
return closest; }
@ContextMenu ("Update Waypoints") function UpdateWaypoints () { RebuildWaypointList(); }
function Awake () { RebuildWaypointList(); }
// Draw the waypoint pickable gizmo function OnDrawGizmos () { Gizmos.DrawIcon (transform.position, "Waypoint.tif"); }
// Draw the waypoint lines only when you select one of the waypoints function OnDrawGizmosSelected () { if (waypoints.length == 0) RebuildWaypointList(); for (var p : AutoWayPoint in connected) { if (Physics.Linecast(transform.position, p.transform.position)) { Gizmos.color = Color.red; Gizmos.DrawLine (transform.position, p.transform.position); } else { Gizmos.color = Color.green; Gizmos.DrawLine (transform.position, p.transform.position); } } }
function RebuildWaypointList () { var objects : Object[] = FindObjectsOfType(AutoWayPoint); waypoints = Array(objects); for (var point : AutoWayPoint in waypoints) { point.RecalculateConnectedWaypoints(); } }
function RecalculateConnectedWaypoints () { connected = Array();
for (var other : AutoWayPoint in waypoints) { // Don't connect to ourselves if (other == this) continue; // Do we have a clear line of sight? if (!Physics.CheckCapsule(transform.position, other.transform.position, kLineOfSightCapsuleRadius)) { connected.Add(other); } } }