I'm making a game in which I have to transform the players position after he completes the objective, but when I transform him, he's stuck in the air on the new transform position, even though I have a Rigibody2D set on it with a gravity scale of 2. When I move him manually by dragging and releasing, he falls to the ground normally. I'm fairly new so any help would be appreciated. I can't seem to identify the problem.
Here's the code,
public GameObject player;
public Transform nextPart;
public Camera cam;
void Start()
{
}
// Update is called once per frame
void Update()
{
if (PlayerController.canTransform)
{
player.transform.position = nextPart.position;
cam.transform.position = new Vector3(nextPart.position.x, nextPart.position.y, -10);
}
}
Here's a picture too,
Your code is within the Update function. This means that so long as canTransform is true your player will be placed at that transform every frame.
You need to set that boolean back to false after moving your player or have some other check to ensure you don't move to that position more than once.
It might be better to instead have the player set to that position in a separate function and simply call it one time when you reaches that objective.
Related
It has two camera angles. First person for engaging gameplay and top-down for 2D game experience. But in top down camera view I can't figure out the rotation of the camera with respect to player.
I wrote the following script for the main(top-down) camera view.
public class FollowPlayer : MonoBehaviour
{
public GameObject player;
private Vector3 offset = new Vector3(0f, 24.953f, -0f);
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void LateUpdate()
{
transform.position = player.transform.position + offset;
}
}`
I tried
transform.rotation = player.transform.rotation;
but it didn't work since camera is on top of player. If I could somehow do
transform.rotation = player.transform.rotation + X axis 90 degree;
That would be perfect but I don't know how to do that.
If I understand you correctly, you want to follow the player from above with your second camera. Leaving some flexibility, the best option I think would be Unity's built in Transform.LookAt(target) method (LookAt), which automatically rotates an object (in your case the camera) so that it faces the target.
Therefore, you could do something like this in your Update, assuming your script is attached to the Camera. Otherwise substitute transform with Camera.main.transform:
transform.LookAt(player);
Note: If you plan to have your camera fixed above your player at all times, it is sufficient if you perform the LookAt once, e.g. in Start and then attach the camera as a child to the player. If your camera does not move with your player in the world but you want it to focus the player anyway, do do it in Update. Hope I addressed your problem:)
My problem has been resolved. I was trying to rotate the wrong axis. My bad.
mouseInput = Input.GetAxis("Mouse X");
transform.Rotate(Vector3.forward * speed * -mouseInput);
I needed to get mouse input from user and change the Z-axis according to it. Game is working fine now.
I have the following setup:
A ball object that has a CircleCollider 2d with a frictionless, full-bounce (1) material. The collider is not a trigger. It also has a rigidbody2d on it, with no gravity, some mass, Continuous collision detection and Interpolate set to Interpolate. It also has a script with this code:
Rigidbody2D rb;
private void Awake() {
rb = GetComponent<Rigidbody2D>();
}
Vector2 lastVelocity;
private void FixedUpdate() {
lastVelocity = rb.velocity;
}
private void OnCollisionEnter2D(Collision2D other) {
if (other.gameObject.tag == "Block" && isPiercing) {
rb.velocity = lastVelocity;
}
}
A few Block objects that have a Box Collider 2d on them (also not set to be triggers), nothing else.
The idea is, if I have the isPiercing property set on the ball, it should pass through. Otherwise, it should use default behaviour and the ball should bounce off the blocks as normal (which it does fine).
What actually happens is, there's some 'jitter'; as soon as the ball hits the block, it looks like it back-tracks on its path slightly. It still passes through; just it looks like it hit a speed bump along the way.
Do I need to move the ball forwards along its path when it enters the collision to make up for the bounce it's about to do (or is in the process of doing)?
Maybe get a clip of what's going wrong, but from what I can see, when the ball hits a block with piercing, then you're setting its velocity to its FixedUpdate() velocity. I don't know why you're doing this, but FixedUpdate() is calculated before unity does its physics calculations. I'm not sure, but it seems as if this may move the ball back slightly, like you are saying.
My suggestion would be to not set its current velocity to its FixedUpdate velocity.
Hope this works!
I have been making a first person game called "shoot the ball into the bin". The camera is in a cylinder as a player also the cylinder has collision.
I have been struggling with the main driver of the game. Like in most first person shooter games, you shoot out from the center point of the camera or the cursor.
I have trouble replicating that. The code I have so far for the shooting is:
Instantiate(prefab, new Vector3(Camera.main.transform.position.x, Camera.main.transform.position.y, Camera.main.transform.position.z), Camera.main.transform.rotation);
(Credits to #derHugo for helping me instantiate a prefab)
But that just spawns it on top of the player, not in front of it. How do I make it shoot away from the player, but also in front of the player, not on top.
In order to spawn in front of that position simply use
// Already reference this via the Inspector if possible
[SerializeField] private Camera _camera;
// Adjust how far in front of the camera the object should spawn
[SerializeField] private float distance;
private void Awake ()
{
// otherwise get it ONCE
if(!_camera) _camera = Camera.main;
}
And then simply add an offset in the direction of Transform.forward of the camera like
Instantiate(prefab, _camera.transform.position + _camera.transform.forward * distance, _camera.transform.rotation);
so it seems when you instantiate the bullets, you are spawning them directly on the position of the camera. You should adjust those values so that it spawns in the center of the screen. To do so, you should divide the y position by 2 or 1.5 depending on how high up the gun is from the ground. Then change the z so that the bullets pushed further in front of the player.
Instantiate(prefab, new Vector3(Camera.main.transform.position.x, Camera.main.transform.position.y / 2, Camera.main.transform.position.z + somearbitraryvalue), Camera.main.transform.rotation);
Next, to get give the bullets a velocity, you should create a separate script for the bullet prefab that is in charge of moving the bullets.
public Rigidbody2D bullet;
bullet = GetComponent<Rigidbody2D>()
void Update(){
bullet.velocity = new Vector 3(0,0,1)
}
Hope this answer helps!
I would like to use a characters tongue so instead of shooting a bullet, it goes toward the enemy, licks it, and comes back. I got this wording from this question: Unity shooting with Tongue 2d game (hasn't been answered and is 4+ years old). The only difference is my character moves.
I have this code from looking at a shooting tutorial so when you click the tongue prefab generates and is at the correct angle. I need it to grow on click and shrink back.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LineController : MonoBehaviour
{
public GameObject player;
private Vector3 target;
public GameObject crosshairs;
public GameObject tonguePrefab;
// Start is called before the first frame update
void Start()
{
Cursor.visible = false;
}
// Update is called once per frame
void Update()
{
target = transform.GetComponent<Camera>().ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, transform.position.z));
crosshairs.transform.position = new Vector2(target.x, target.y);
Vector3 difference = target - player.transform.position;
float rotationZ = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;
if (Input.GetMouseButtonDown(0))
{
shootTongue(rotationZ);
}
}
IEnumerator shootTongue(float rotationZ)
{
GameObject t = Instantiate(tonguePrefab) as GameObject;
t.transform.position = new Vector2(target.x, target.y);
t.transform.rotation = Quaternion.Euler(0.0f, 0.0f, rotationZ);
yield return new WaitForSeconds(2000);
t.SetActive(false);
}
}
I was also trying to make it disappear after whatever time and with that it doesn't work at all?
If the prefab is just a line with a simple texture I suggest using a line renderer:
Create an empty transform that starts on the mouth and then it move untill it reaches the crosshair. The movement is done using Vector2.MoveTowards.
Your tongue will no be a line renderer component. This line renderer will have 2 points, the start which is static, and the end which you have to update on the Update() for example, to correspond to the positions of the empty transform in item 1.
If you really wish to expand a tongue gameobject instead, then you are going to need a bit of math, this answer has what you need but in 3D:
https://answers.unity.com/questions/473076/scaling-in-the-forward-direction.html
1) I suggest creating sprite/sprite sheet animations with Mecanim or relatively new Skeletal Animation with Anima2D. With these systems you can create nice animations, transitions, even animate the sphere collider to trigger collisions and actions, change active state of your objects, etc. and control the animation with very little code. This way you can get best effects in my opinion.
As tongue is not a bullet... :) You only need one. I don't think you want to Instantiate/Create prefabs every time you press the lick button. Instead you should just turn your tongue object on/off (gameObject.SetActive). You can also change your object active state within the animation. So if you don't know how to code it you can do most of it in the Animation window and use very simple code to play the animation when you press the lick button. Whenever a sphere collider touches something you can tell the Animator Controller to play a 'roll back' animation and it will transition nicely to the start position.
There are many tutorials about Mecanim, Animations, 2D Animations, Anima2D, Animator Controller out there.
2) If you need very good control over the tongue you could create a custom mesh and control it via script but this is far more difficult.
3) The reason why your object is not turning off is probably because you wrote WaitForSeconds(2000) so it will turn off after 2000 seconds - more than half an hour. You should also call it with StartCoroutine(shootTongue()) as it is a Coroutine. Again if you want to turn off the object don't create new ones every time. If you want to keep creating new objects you should Destroy the objects instead. Otherwise you will end up with a lot of deactivated tongues in your scene and I don't think you needs that many tongues.
There are two similar scripts that makes the same thing(The Camera is following the player).The first, is what I wrote and the second one, is from the unity tutorial.Which one is more reliable and why?
1st
public class CameraController : MonoBehaviour {
public GameObject player;
void LateUpdate () {
transform.position = new Vector3 (player.transform.position.x, player.transform.position.y,-10f);
}
}
2nd
public GameObject player;
private Vector3 offset;
void Start ()
{
offset = transform.position - player.transform.position;
}
void LateUpdate ()
{
transform.position = player.transform.position + offset;
}
There is no such thing as reliability between the two scripts. Although, I would encourage you to use the second script.
The first script is assigning the camera's position with the position of the player. The only thing it doesn't assign is the z-axis which you hard-coded to -10. When game starts, the camera will be moved to where the player is. The z- axis of the camera will be set to -10. This happens every late update.
The second script is assigning the camera's position with the position of the player and offset value taken in the start function. When game starts, the offset distance between the camera and the player is retrieved in the Start function. In the LateUpdate function, the player's position is retrieved and the offset is added to it and is then applied to the camera's position.
The result of the first script is that the camera will always be position where the player is but the z axis will always be set to -10. I am sure you don't want the z axis to not be moving.
The result of the second script is that the camera will always have the-same distance between it and the player. Even if you move the camera or player from the Editor, the second script will automatically adjust the position and make sure that the distance between the camera and the player before the game started is always the-same. I am sure this is what you are looking for but I wouldn't call this reliable. The first code is simply not appropriate for what you are doing , the second code is.
I would bet that the second one is more reliable because it doesn't have any hardcoded variables. But it's also easy to use to programmers and none programmers since it calculates the offSet you want to give in any direction based on the position you set on the scene.