-2

This is code for a turret who shoots lasers at a player, a capsule. The lasers currently come out in a wrong rotation, it's upright rather than how a laser usually looks.

My code works perfectly so far, no bugs. How do I fix this?

void SpawnLaser(int iter)
{
    for (var j = 0; j < 5; j++)
    {
        Vector3 pos = transform.position;
        var rotation = transform.rotation;
        rotation *= Quaternion.Euler(0, 90, 0);
        Instantiate(projectile, pos, rotation);
    }
}
CodingTigers
  • 13
  • 1
  • 5
  • Is this a 2d game? Are these sprites or meshes? What local axis of `transform` is the "front" of the turret? What local axis of `projectile.transform` is the "front" of the laser? The post is currently too broad if it is asking about rotating the lasers and asking about collision. The part about collision should be a separate question. – Ruzihm Apr 05 '21 at 22:13
  • Don't do any of that., Just use **Rotate** – Fattie Apr 05 '21 at 22:13
  • Also, what type is `projectile` and what components are attached to its gameobject (assuming it has one)? Basically, this post needs a [mre]. See [ask] for more information. – Ruzihm Apr 05 '21 at 22:26
  • Uhhhh, for the people who closed it, the info is confusing. What should I edit? – CodingTigers Apr 06 '21 at 01:26
  • Projectile is just a game object. – CodingTigers Apr 16 '21 at 04:53

1 Answers1

0

I am not entirely sure the goal of your code, but I can offer a little guidance, and can edit my answer when I know more about your issue.

Nothing is wrong with your spawning, the issue most likely has to do with your movement. Another issue is your rotation is being multiplied as a local variable, so each laser will be pointing in the same direction.

    // my laser object
    [SerializeField] private GameObject projectile = null;

    private void Update()
    {
        // when I hit space, spawn new lasers
        if (Input.GetKeyDown(KeyCode.Space))
            SpawnLaser();
    }

    void SpawnLaser()
    {
        // keep the rotation outside of the loop so the *= 90 will change the angle the object is positioned to look at
        var rotation = transform.rotation;

        // as the angle is *= 90, there are only 4 possible rotations, so I would adjust your loop or rotation product
        for (int j = 0; j < 4; j++)
        {
            Vector3 pos = transform.position;
            rotation *= Quaternion.Euler(0, 90, 0);

            // I attached a rigidbody to move the objects, if your objects or your player do not have rigidbodies, then they will not collide
            Rigidbody laserObj = Instantiate(projectile, pos, rotation).GetComponent<Rigidbody>();

            // I am adding a force of 10 in the forward direction of my newly spawned laser
            laserObj.AddForce(laserObj.transform.forward * 10f);
        }
    }

Make sure to add a rigidbody component and collider component to the prefab that is spawning. Something else you will need to do is add a layer onto the lasers so they do not collide with each other. Look into Layer-based collisions. Make sure to give a layer to your laser and disable the collision with itself so it does not collide with other lasers.

As for your issue with collision, there are many reasons so instead of listing them here, I'll link to an answer that goes over the possible reason.

Edit: After more information given this might be closer to what you are trying to achieve.

    // this script is on the object that will be firing the laser, a turret, gun, etc.

    [SerializeField] private GameObject projectile = null;      // laser prefab 
    [SerializeField] private Transform playerObjectPos = null;        // reference to what we are trying to aim at (player, enemy, etc.)

    private float laserFiringForce = 10f;

    private void Update()
    {
        // when I hit space, spawn new laser spawns
        if (Input.GetKeyDown(KeyCode.Space))
            SpawnLaser(playerObjectPos);
    }

    /// <summary>
    /// Spawns a laser aiming at a specified target
    /// </summary>
    /// <param name="target"></param>
    void SpawnLaser(in Transform target)
    {
        // lock our rotation to only Y-axis
        Vector3 targetPosition = new Vector3(target.position.x, transform.position.y, target.position.z);

        // have our turret / player / etc. look at the target position
        transform.LookAt(targetPosition);

        // instantiate a laser at the position of our turret / player and have its rotation aim in the same direction as our turret / player
        // while grabbing the reference to the rigidbody component on the laser so we can add a force to it (Note: You can have the movement logic on the laser itself instead of doing it here)
        Rigidbody laserObj = Instantiate(projectile, transform.position, Quaternion.LookRotation(transform.forward, Vector3.up)).GetComponent<Rigidbody>();

        // add a force in the direction the laser is facing so it moves
        laserObj.AddForce(laserObj.transform.forward * laserFiringForce);
    }

I would look into a tutorial you can follow for an FPS or 3D Turret game. Given the questions I would think you are newer to either programming, Unity or both. If this is one of your first projects, look into a tutorial, create it and change it to be more yours. After a few tutorials completed you should have a better understanding of Unity. If you are new to programming all together, I would also consider looking into classes, documentation, etc. of both c# and programming in general.

To get you started in Unity, try Brackey's. The tutorial I linked is his episode 4 of a 3D tower defense game where he goes over making the turrets.

TEEBQNE
  • 6,104
  • 3
  • 20
  • 37
  • Uhhhh, It ended up shooting lasers in four directions. What I want is a turret that shoots lasers base on its position. Sorry if it was a little confusing. Currently, the player doesn't collide with the lasers and move too. – CodingTigers Apr 05 '21 at 21:37
  • Do you want a laser that targets an object and fires a laser at that object? And the laser tracks and hits the target even if it moves? Your previous code was spaning 4 lasers on top of each other. The reason why I split it the way I did as I thought that was not what you wanted to do as it did not make too much sense to me. – TEEBQNE Apr 05 '21 at 22:10
  • Yes but I don't want the laser to track. I didn't realize it was spawning 4 lasers on top of each other! – CodingTigers Apr 05 '21 at 22:13
  • Gotcha. So you want a laser shoot that will target, and shoot at a position then? – TEEBQNE Apr 05 '21 at 22:16
  • Yes, at the player. – CodingTigers Apr 05 '21 at 22:16
  • I posted an update that should work. Also left a comment at the end. – TEEBQNE Apr 05 '21 at 22:29
  • Thank you, I actually watch Brackey's videos, though I didn't know he had a tutorial on tower defense! – CodingTigers Apr 05 '21 at 22:30
  • Of course! Hope I could help. His tutorial should go a lot more in-depth about calculating how to target a player. I haven't watched it but I assume he would bring the players direction, velocity and acceleration into account so the turrets feel more alive as if it is lively targeting you. – TEEBQNE Apr 05 '21 at 22:32
  • Hmmm, I tried testing the code, but I couldn't drag my player object into the transform variable box. (I am new to Unity but definitely not coding) – CodingTigers Apr 05 '21 at 23:04
  • Are you sure? If the player object has a Transform component meaning it has a position, rotation and scale then it should be acceptable. It is just looking for any type that matches Transform. – TEEBQNE Apr 05 '21 at 23:19
  • I got it working but the turret is tilting down and going the opposite way, haha. It's now evading my player. – CodingTigers Apr 07 '21 at 18:24
  • It must mean your asset is oriented in the wrong direction. I would try changing the pivot on your turret asset. If you made it yourself in Maya / ZBrush then re-export it with a pivot that allows the turret to have a forward that faces the side of its firing portion. If it is consistently off, you can also try subtracting Valueº in the Y component of the rotation transform of the parent. That should set the turret to rotate to look at the player. As for looking down it is because it is look directly at the player. Just set the Z component of rotation to transform.rotation.z – TEEBQNE Apr 07 '21 at 18:35
  • @CodingTigers I updated the snippet. It should only rotate in the Y-axis now so it won't go down. The other issue is an issue with your asset I believe. Try to subtract a constant value from the rotation until it looks right. – TEEBQNE Apr 07 '21 at 18:42