I'm totally new with Unity (and game development in general). I followed the great simple tutorial Survival Shooter and I have one question: in this tutorial, we add a Y constraint position to the rigidbody's character plus we set the drag value and the angular drag value to infinite. How can we make the character jump since those settings prevent the character from moving to the Y axis?
If someone can give me an hand on that please...
Thanks a lot!
Why exactly do you add the constraint on the Y axis? You could remove it, and then just add gravity that will make your player stick to the ground. After that just apply a force, or just a simple translation going upwards by a set speed, to make the player jump and then wait for gravity to bring him back down.
This is what I would do to jump.
P.S. you need to remove the constraints on the Y axis on the vector
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spawner : MonoBehaviour
{
public Vector3 force;
public Rigidbody rb;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.Space) && transform.position.y == 0) //Enter your y axix where ground is located or try to learn a little more about raycasting ill just use 0 for an example)
{
rb.AddForce(force);//Makes you jump up when you hold the space button down line line 19 will do so that you only can jump when you are on the ground.
} if (Input.GetKeyUp(KeyCode.Space))
{
rb.AddForce(-force); //When you realase the force gets inverted and you come back to ground
}
}
}
I would do this instead edit the code over this post.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Just : MonoBehaviour {
public Vector3 force;
public Rigidbody rb;
bool isGrounded;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && isGrounded == true) //Rember to got to your "Ground" object and tag it as Ground else this would not work
{
rb.AddForce(force);
}
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Ground")
{
isGrounded = true;
}
}
void OnCollisionExit(Collision collision)
{
isGrounded = false;
}
}
You need to assign your ground object a tag called Ground, You need to make your own tag called Ground its not that hard tho you click your object and top left of the inspector there's the tag and then u just make a new tag called Ground. And also plz rember to assign the other values on your player object.
Related
I tried to make this object move down but everytime it goes out of the screen it teleports back up with a different x position but it appears in random places on screen and collides with things. it only has this script and a rb2d and a boxcollider2d. rb2d doesnt have gravity,collision detection continious,interpolate interpolate,sleeping mode never sleep.im new to unity
this is the code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Teleport : MonoBehaviour
{
public Rigidbody2D rb;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update(){
}
void FixedUpdate(){
rb.velocity=new Vector2(0f,-5f);
if (rb.position.y<-5.5f){
float rndf= Random.Range(-10.14f,10.14f);
rb.MovePosition(new Vector2(rndf,5.5f));
}
}
}
here is a photo of the editor
It was because i moved it and didn't teleport it. It collided with objects on the way
In my game on unity 2d I have spaceship and a planet. The planet is orbiting a star so I made a script that parents the planet to the player when I get within a range so the planet doesn't fly past or into the player. This script makes the player move with the planet so they land on it and fly around it easily.
Here is the script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ParentPlayer : MonoBehaviour
{
[SerializeField] GameObject Player;
private float Dist;
[SerializeField] float Threshold;
private CircleCollider2D ParentTrigger;
// Start is called before the first frame update
void Start()
{
ParentTrigger = GetComponents<CircleCollider2D>()[1];
ParentTrigger.isTrigger = true;
ParentTrigger.radius = Threshold / transform.localScale.x;
}
// Update is called once per frame
void Update()
{
}
private void OnTriggerEnter2D(Collider2D collider)
{
if(collider.gameObject == Player)
{
collider.gameObject.transform.SetParent(transform);
}
}
private void OnTriggerExit2D(Collider2D collider)
{
if(collider.gameObject == Player)
{
collider.gameObject.transform.SetParent(null);
}
}
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, Threshold);
}
}
The problem is that as the planet rotates it ends up moving the player that has been parented to it. How can I make the planet's rotation not affect the position and rotation of the player, but still make the planets position affect the position of the player?
This might not be what you're looking for but I'm going to add it reguardless. Given that the Child-object will follow the parent, I would suggest putting the planet and spaceship as a child of the empty gameobject. Then you could rotate the the planet object, and if planets are in movement, you could add the movement to the parent object.
How about instead of parenting the player, write a script to set its position to the planets + some offset, and then the rotation wouldn't be an issue. Alternatively, if the player doesn't rotate at all, add constraints to its Rigidbody. Maybe something like this:
player.transform.position = planet.transform.position + offset;
Hope that works!
I added a particle system to my unity project. But I can't make it attach to a certain game object or tag. How can I make a Particle System sit on the center of a cube, while it's getting played once if the player triggers with this cube?
Code used for the trigger to work:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Collision_Player_grower : MonoBehaviour
{
public GameObject Player_grower;
public ParticleSystem CollisionGrower;
// Start is called before the first frame update
void Start()
{
times_player_grower = 0;
CollisionGrower.transform.position = Player_grower.transform.position;
}
// Update is called once per frame
void OnTriggerEnter(Collider collision)
{
if (collision.gameObject.tag == "Player")
{
print("we hit an playergrower");
CollisionGrower.Play();
Destroy(Player_grower);
}
}
}
Note: It does work if I manually place the particle system in the heart of the cube, but I assume this can be done in an easier way.
From what I understand, you want the position of the particle system to be in the center of another object.
1)
You could do that simply by attaching a particle system game object as a child of the cube you were talking about.
2)
You could do this with code instead. In case you want the particle system to do something extra, you could just adjust the code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Collision_Player_grower : MonoBehaviour
{
public GameObject ParticleSystemObject;
public GameObject Cube;
public GameObject Player_grower;
public ParticleSystem CollisionGrower;
// Start is called before the first frame update
void Start()
{
times_player_grower = 0;
CollisionGrower.transform.position = Player_grower.transform.position;
}
// Update is called once per frame
void Update()
{
ParticleSystemObject.transform.position = Cube.transform.position;
}
void OnTriggerEnter(Collider collision)
{
if (collision.gameObject.tag == "Player")
{
print("we hit an playergrower");
CollisionGrower.Play();
Destroy(Player_grower);
}
}
}
I don’t fully understand what the rest of the variables are for, and what they are, so I may have done some un-needed things.
First, I added two GameObject variables. One of them is the cube object you want the particle system to go to, and the other is the particle system as a game object. I set the position of the particle system to the position of the cube.
Important: if you have this script attached to the cube, remove the Cube variable.
Instead of using
... = Cube.transform.position;
Use
... = transform.position;
I'm making a game in unity where the user drags to shoot a ball at some objects at a distance. So far I have this DragAndShoot script:
//using System.Collections;
//using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(Collider))]
public class DragAndShoot : MonoBehaviour
{
public Transform prefab;
private Vector3 mousePressDownPos;
private Vector3 mouseReleasePos;
private Rigidbody rb;
private bool isShoot;
void Start()
{
rb = GetComponent<Rigidbody>();
}
private void OnMouseDown()
{
mousePressDownPos = Input.mousePosition;
}
private void OnMouseUp()
{
mouseReleasePos = Input.mousePosition;
Shoot(mouseReleasePos-mousePressDownPos);
}
private float forceMultiplier = 3;
void Shoot(Vector3 Force)
{
if(isShoot)
return;
rb.AddForce(new Vector3(Force.y,Force.x,Force.z) * forceMultiplier);
isShoot = true;
createBall();
}
void createBall(){
Instantiate(prefab, GameObject.Find("SpawnPoint").transform.position, Quaternion.identity);
}
}
As you can see, I made the function createBall() in order to respawn a ball prefab at the position of the game object SpawnPoint. When I run the game, the first ball shoots fine. And another ball respawns.
Issue: when I shoot the second ball and it moves, one more ball seems to have appeared at the second ball somehow, and it moves as well. Not sure why this is happening and how to fix it - can someone pls help? Thanks.
The problem is that you need to Destroy() the game object you threw first. Since you are just bringing the objects back when click down again, here is what you should do:
Make it so that it destroys the old object. Because you just keep instantiating the object, then when you throw it again it throws the old one too. If you understand what I mean, then hopefully, you can turn this into what you want. (It wasn’t exactly clear what your game was; this is what I interpreted)
I'm using unity and when the enemy shoots, the bullet passes right threw the player. I don't know how to solve this. Here's my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyBullet : MonoBehaviour
{
public float speed;
public Rigidbody2D rb;
private Transform player;
private Vector2 target;
private Vector2 moveDirection;
// Start is called before the first frame update
void Start()
{
player = GameObject.FindGameObjectWithTag("Player").transform;
moveDirection = (player.transform.position - transform.position).normalized * speed;
}
// Update is called once per frame
void Update()
{
rb.velocity = new Vector2(moveDirection.x, moveDirection.y);
//transform.position = Vector2.MoveTowards(transform.position, target, speed * Time.deltaTime);
}
void OnCollisionEnter2D(Collision2D other) {
if (other.gameObject.tag == "Player") {
Destroy(this.gameObject);
}
}
}
I put a tag named BulletEnemy on the bullet but it doesn't work
How fast is your speed value?
At high speeds a bullet might move farther in one frame than the depth of the object you want it to hit. You can still detect collisions by every frame storing the position of your bullet as a vector and on the next frame casting a ray between the current position and the last known position in the previous frame. If the ray hits your enemy then call the same function that you would on a physics collision.
There is no way to do it with only OnCollisionEnter because of the effect of bullet speed.
Check your bullet's speed. if they are too fast, your physics engine just ignore the collision and therefore no OnCollisionEnter will be called.
Use larger Collider for your player. and also check Player tag on your player object. also make sure your tagged object has Collider2D component.
Change OnCollisionEnter2D to OnCollisionStay2D. if you want to Destroy bullet, there will be no difference in runtime