The only way I know to detect collision is through a trigger. Therefor, I have a paddle hitting the ball and a trigger to keep the score. However, for some reason the trigger paddle won't folloWhen I move up, the trigger paddle follows behind the normal paddle slightly then returns to it's initial position. Here is a picture of the paddle bar, the trigger is inside the normal paddle.
and here is the code to move the paddle, they have the same script but the trigger won't act correctly. Also note, that it says in the position bar on the right of the image for the trigger paddle that it is following the paddle. But it is not
void Start () {
dimensions = new Vector3(transform.localScale.x, transform.localScale.y, 0);
transform.localScale = new Vector3(.5f, .5f, 1);
}
// Update is alled once per frame
void Update () {
yPos = gameObject.transform.position.y + (Input.GetAxis ("Vertical") * paddleSpeed);
if(Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.S))
playerPos = new Vector3 (gameObject.transform.position.x, Mathf.Clamp(yPos, -yClamp, yClamp), 0);
gameObject.transform.position = playerPos;
}
I can't figure out why it won't work. Any help is extremely appreciated seeing as I have no help looking online and can't figure it out.
If you simply want the 'trigger paddle' to follow the position of the visible paddle then put the trigger paddle as a child of the visible paddle in the heirarchy (It looks like you've done this already). Nothing else is needed. Remove script you have assigned to make the trigger paddle move in the same way that the regular paddle does.
also, if you want to detect a collision properly then use OnCollisionEnter2D
also also, I know you most likely just want to get this working, but this can be done in a much better way. You don't need the child object at all. Just attach the BoxCollider2D component to the visible paddle and detect the collision from there.
Related
I'm making a very simple 3D game in Unity where I have this space shuttle I can move around in space around asteroids and I can shoot when pressing/holding the mouse button. I'm doing this by Instantiating a sphere at the "Emitter" transform.position and then just applying a forward Force to that bullet object.
It all works fine, but the one thing I don't like and also don't know how to fix is how the bullets keep their position when shooting and moving the mouse left-right, instead of keeping a perfectly straight line at all times.
This is how it looks when I'm shooting and moving my camera at the same time:
Screenshot while shooting
Here's a gif for better visualization.
Right now it looks like I'm pissing lasers, which is never good. I tried making the bullet speed a lot faster, but then the bullets become harder and harder to see and it doesn't look as good.
This is the code by which I'm shooting the bullets:
private void Fire()
{
GameObject bullet = Instantiate(laserPrefab);
GameObject bullet2 = Instantiate(laserPrefab);
Physics.IgnoreCollision(bullet.GetComponent<Collider>(), shuttleCollider.GetComponent<Collider>());
Physics.IgnoreCollision(bullet2.GetComponent<Collider>(), shuttleCollider.GetComponent<Collider>());
bullet.transform.position = laserEmitter.position;
bullet2.transform.position = laserEmitter2.position;
/*Vector3 rotation = bullet.transform.rotation.eulerAngles;
Vector3 rotation2 = bullet2.transform.rotation.eulerAngles;
bullet.transform.rotation = Quaternion.Euler(rotation.x, transform.eulerAngles.y, rotation.z);
bullet2.transform.rotation = Quaternion.Euler(rotation2.x, transform.eulerAngles.y, rotation2.z);*/
bullet.GetComponent<Rigidbody>().AddForce(laserEmitter.forward * laserSpeed, ForceMode.Impulse);
bullet2.GetComponent<Rigidbody>().AddForce(laserEmitter.forward * laserSpeed, ForceMode.Impulse);
StartCoroutine(DestroyBulletAfterTime(bullet, bulletDeathTime, bullet2));
}
Don't mind the commented lines, I was just messing around trying to see if I can get it to work. The shooting behaves the same with or without those commented lines.
Of course, a projectile based system will behave and look like a projectile system.
If you want laser behavior use a LineRenderer. Raycast where your laser line should end (either laser max distance or the point of hitting an object in range).
If you don't like the "static" looks of it, change the LineRenderer Material to something that changes over time (search for shaders/ LineRenderer effects).
I have a game where map/background is made up of prefabs. My player and prefabs both have rigidbodies and colliders. Neither of them have is trigger checked and the prefabs have collision detection set as continuous dynamic. The player's collision detection is set on continuous. Each of the prefabs have a mesh collider and the individual walls of the prefabs have box colliders (none are set to is trigger). I keep trying to test it on my phone using Unity Remote 5, and every time I move the player it goes through the walls. If anyone has any advice on how to prevent my player from going through the walls, I would really appreciate it!
My movement script is:
public class Movement : MonoBehaviour
{
private Touch touch;
private float speedModifier;
void Start()
{
speedModifier = 0.01f;
}
void Update()
{
if(Input.touchCount > 0)
{
touch = Input.GetTouch(0);
if(touch.phase == TouchPhase.Moved)
{ transform.position = new Vector3(transform.position.x + touch.deltaPosition.x * speedModifier,
transform.position.y,
transform.position.z + touch.deltaPosition.y * speedModifier);
}
}
}
}
It would really help to see your movement script however it sounds like you are moving player by manipulating transform.position or using rigidbody.MovePosition() without setting isKinematic to true. The documentation says;
If the rigidbody has isKinematic set to false, it works like transform.position=newPosition and teleports the object to the new position (rather than performing a smooth transition).
This behaviour will ignore the collision. Also you don't need rigidbody on every GameObject in the scene. 1 rigidbody on the player is enough to collide it with other objects.
depend on what I got from your question, when you are playing and the player hit the wall, it goes inside; so the problem might be the mass of the wall. if you must add a Rigidbody to the wall so you need to add more mass to the wall also edit the border of the box collider and make them reasonably a bit wider, otherwise if you dont need a rigidbody on the wall simply keep just the box collider and it will works good. hope this answer help you, and it will be better if you can explain more the situation using some pics.
Using the Rigidbody position or applying force tends to cause the Rigidbody to clip through other colliders. I recommend changing rigidbody.velocity instead of directly changing the position.
I'm developing an enemy AI in a 2D Game that I'm working on. This enemy swims and I wanted to make a "floating effect" animation for the enemy, so I made an animation where the Y Axis of the game object bounces up and down.
I Use transform.Translate() to move the enemies in the game and it worked just fine until I made this animation. But, when the animation is playing, the enemy can't move in any direction.
public virtual void Move(float speed)
{
if (canMove)
{
transform.Translate(new Vector2(speed, 0) * Time.deltaTime);
}
}
Once you have a keyframe in any state of your animator for a certain property the animator will always overrule any changes done in a script because the animation updates are all done after Update. You could try to either move your code to LateUpdate.
Or in your specific case you do not want the x component of your position keyframed at all. Simply remove all the keyframes for the x (and z) component(s) of the position from the animations so only y has keyframes. This should solve your problem.
Alternatively use your movement script on a GameObject on a higher level in the hierachy as your Animator - meaning add a new GameObject, make the animated object a child of it and place your movement script instead on that parant object.
I want a gameobject spinning around its y-axis. This spinner should have a initial movement direction and when colliding with something, it should change its direction.
I created a little picture to show what I mean, but I want the behaviour for a 3D game.
So I just started with the rotation of the spinner,
public class Spinner : MonoBehaviour
{
[SerializeField]
private float movementSpeed; // speed when moving
[SerializeField]
private float rotationSpeed; // speed when rotating
private Rigidbody rigid;
private Vector3 movementDirection; // the direction the spinner is moving
private void Start()
{
rigid = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
transform.Rotate(0, rotationSpeed, 0); // rotate the spinner around its y-axis
}
private void OnCollisionEnter(Collision col)
{
// set new direction
}
}
How can I move the spinner, that it moves along a direction and whenever it collides with something, it changes its direction. It should never stop moving or rotating.
I would like to point out a few things:
The Unity Physics Engine will make collisions to absorb part of the force which moves your spinner, so unless you keep adding "artificial" forces to the spinner it will eventually stop.
The "air friction" in your scene will also reduce the force of your
spinner, so it will slow it down. You should add a material to the
spinner which has 0 Dynamic Friction
Based on the comment you left in #reymoss' answer, you may consider
to add the bouncy material to the walls, and not to the spinning
GameObject.
To sum up, the issue here is if you want a GameObject to bounce against a wall using the Physics Engine, the object will eventually stop, because some of the forces will be absorbed in each collision. That means you will need to keep adding external forces every time a collision takes place, to keep it moving endlessly.
Something you can try is,
1- Add a bouncy material to the walls and remove the dynamic friction of your spinner. In the following link you can learn about this:
https://docs.unity3d.com/Manual/class-PhysicMaterial.html
2- Add to the Spinner a Collider, so when it detects a collision with a wall (you can tag the walls as so for example) add an additional force to the spinner in the direction it is already moving, so it will compensate the energy lost during the collision.
void OnTriggerExit(Collider other) {
if(other.tag == "wall") {
rigidbody.AddForce(rigidbody.velocity.normalized * Time.deltaTime * forceAmount);
}
}
The idea is to let the Engine decide the direction of the Spinner after the collision with the wall, and as soon as the GameObject leaves the trigger, you add an additional force in the current direction.
Then you can play with the Bounciness of the wall's material and with the forceAmount, until your spinner moves as you have in mind.
Note: Since you will have 2 materials, one in the walls and another in the spinner, maybe playing with the Friction Combine and Bounce Combine you will be able to avoid the force lost during collisions, so you will not need to add the external force I mention in the second step. However I have never tried this.
Let me know if it works. I can't try myself the solution until I arrive home.
If you give the object an initial velocity, attach a collider, create and assign a Physics Material 2D to the collider (to apply bounciness), and attach Colliders to the walls, you can have it bounce around with minimal code.
private void Start()
{
rigid = GetComponent<Rigidbody>();
rigid.velocity = new Vector3(2f, 3f, 1f) // initialize velocity here
}
I have a Light_Spell script attached to a magic wand which is parented to a Razer Hydra hand object. The Light_Spell takes a prefab of a Light which is projected out of it when a button is pressed.
However the light is just moving up, no matter what way I rotate the hand object, it always goes up. I had it working but I changed some code around and can't remember how I got it working in the first place.
Here is the code I have so far:
//What happens when bumper is pressed
if (isSelectedSpell && SixenseInput.Controllers [0].GetButtonDown (SixenseButtons.BUMPER) && triggerIsPressed == false) {
Rigidbody instantiateProjectile = Instantiate(projectile, transform.position, transform.rotation) as Rigidbody;
instantiateProjectile.position += Vector3.down * 20.0F;
}
I have tried setting Vector3 to up and forward and a whole set of different things. Any ideas on what I should do to make it match the rotation of where the hand is pointing and stuff?
Thanks
Consider using:
instantiateProjectile.position += -instantiateProjectile.transform.up * 20.0f;
Explanation:
Vector3.down is not relative to the transform's rotation, it is a 'down' in World space, that is to say it will always be going down according to the cardinal axes.
transform.up is relative to that transform's rotation. If the projectile is rotated, the axes used to obtain "up" are rotated too. We must use an inverted transform.up instead of transform.down because no transform.down exists.