another question, my player is a square, and when he hits this pressure plate for example, this happen: https://i.gyazo.com/7866da3f8371aee6c319fd447f1bee95.gif
My code in the pressure plate object is this:
Animator pressionar;
public Transform playerCheck;
public LayerMask playerLayer;
public bool pressured = false;
void Start () {
pressionar = GetComponent<Animator>();
}
void Update () {
pressionar.SetBool("Pressionado", pressured);
pressured = Physics2D.OverlapCircle(playerCheck.position, 0.15f, playerLayer);
}
I tried changing to circle collision but didn't change nothing, thanks.
There are a few possible ways to solve this that I can think of.
First: Try locking the rotation of the square's z axis in the RigidBody2D. It's within the Constraints section.
Second: Try creating a ramp for the square to slide onto the button. You could do this using a Polygon Collider. See link for details.
http://docs.unity3d.com/Manual/class-PolygonCollider2D.html
Third: Use a script to activate an OnCollisionEnter function that would place the square onto the button, or to push down the button, which would allow the cube to slide on. See link for details.
http://docs.unity3d.com/ScriptReference/MonoBehaviour.OnCollisionEnter2D.html
Hopefully these resources can be of some help to you. You can mix and match to try and find a method that gives you the best result.
Related
I am new to using unity and am having a real problem getting trigger collisions to register.
public void OnTriggerEnter2D(Collider2D other)
{
print("collide");
if (other.CompareTag("Fish"))
{
print("Caught");
}
}
I have 2D polygon colliders and a rigid body on both items. I have also got 1 set a trigger(have tried having both as trigger). However one UI item is a sprite and the other is an image.
Both items are also tagged with "fish"
Would really appreciate any help.
Thanks
There are four things I can think of which need to happen so that OnTriggerEnter gets called:
The two objects' colliders need to actually be overlapping. Just because their rendered pixels are overlapping, doesn't mean their colliders are overlapping. This can be checked in the editor. Their colliders are indicated with a green outline in the Scene tab. If you don't see anything, make sure the button labeled Gizmos is turned on.
The two objects need to be in physics layers which are set to collide with each other. You can check this in Edit > Settings > Physics2D > Layer Collision Matrix.
Both objects need to have Rigidbody2D components attached. Make sure these aren't Rigidbody components, as those are for 3D physics.
The object which contains the OnTriggerEnter2D event needs to have isTrigger = true.
I've tried several things to do.
First I've checked recommendations from another post.
In nutshell:
Checked if I have rigid body at least for one of objects
Checked layers
Checked tags
Played with "is trigger".
Finally, the solution was to add script to object via create and add component button and not to drop written script to it. Have no idea, but for me that was the solution. Even it was same script.
Both a Sprite and an Image can collide with another Image. What might be wrong is that your sprite may look like touching the image however in the scene the canvas might be far away, so camera may deceive you. Here is the sample code for my tests:
Script that moves the Sprite:
private Rigidbody2D _rigidbody;
private void Awake() => _rigidbody = GetComponent<Rigidbody2D>();
private void FixedUpdate()
{
if (Input.GetKey(KeyCode.A))
{
var movement = -transform.right * Time.fixedDeltaTime * 250;
_rigidbody.MovePosition(transform.position + movement);
}
if (Input.GetKey(KeyCode.D))
{
var movement = transform.right * Time.fixedDeltaTime * 250;
_rigidbody.MovePosition(transform.position + movement);
}
}
Trigger script on image:
private void OnTriggerEnter2D(Collider2D other)
{
Debug.Log(other.name);
}
Nothing helps for me, but in my case I didn't know there was a place in code that breaks collision layers (that is do not change the collision matrix settings visually):
Physics2D.IgnoreLayerCollision(...
Check that too and make sure it is not called.
I'm trying to understand how to get the closest to a destination with Unity's navigation system when a Nav Mesh Obstacle is in the way.
I have this example with a Capsule obstacle (with Carve on) and a capsule agent managed with a script. It seems to work okish, but when I "click" on the obstacle to set the destination of the agent (to a point inside the carved area), the agent moves to another location around the obstacle.
How can I make the agent go to the closest point around the obstacle or to the closest point to the selected destination (that is inside the area of the obstacle)?
Script to move the agent
using UnityEngine;
using UnityEngine.AI;
public class CapsuleMovement : MonoBehaviour {
NavMeshAgent agent;
public NavMeshPathStatus partial;
void Start() {
agent = GetComponent<NavMeshAgent>();
}
void Update() {
if (Input.GetMouseButtonDown(0)) {
RaycastHit hit;
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100)) {
agent.destination = hit.point;
}
}
}
}
Take the center of the clicked objects position and move it slightly towards the moving unit/player, then use that position as your coordinate instead of the direct mouse click.
If that doesn't work.
This is not a guaranteed answer as that is hard to give in a situation such as this, but I hope this brings you further.
I suspect that it may be the coordinate you click, which something is not working out as it should with. Try spawn a "ClickObject" which can just be a coloured sphere, at the position of the mouse click. That way you can confirm where the click actually is happening.
Here is furthermore 2 methods that may come in handy when working with NavMeshes and positioning.
You could try use SamplePosition.
https://docs.unity3d.com/540/Documentation/ScriptReference/NavMesh.SamplePosition.html
Finds the closest point on NavMesh within specified range.
Perhaps also FindClosestEdge
https://docs.unity3d.com/530/Documentation/ScriptReference/NavMesh.FindClosestEdge.html
Locate the closest NavMesh edge from a point on the NavMesh.
Ok so I'm completely lost on how to approach this problem. I have a implementation of IPointerClickHandler that goes something like this :
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log(gameObject.name);
//Othe rstuff
}
So at least every object with this attached to it should print out its name to the console. Now I have 2 screenshot to further Explain the Problem.
The two tiles with the lilipop and the briefcase do not fire OnPointerClick when the camera is in this position.
Move the cam a bit to the right and the event is firec correcrtly.
What have I checked/tried:
Nothing is blocking the object
The camera has a 2D Physics Ray caster attached to it. Its layers are correct.
The tiles have BoxCollider2Ds.
Edit: Did a simple raycast test; THis is the code attached to the camera. This hits from any position as long as even part of the collider is vissible on screen. While if even a part of the collider is near the edge of the viewport or outside of it. OnPointerClick does not work. How do I solve this?
public class RayCasterTest : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast(pos, Vector2.up, 0.0f);
if (hit.collider != null)
Debug.Log(hit.collider.gameObject.name);
}
}
Ok so how do I explain this. I have a big 2dBoxcollider behind everything. I use it as camera bounds. Now for some reason from time to time the EventSystem would hit it and not the correct collider that is definitely on top if it. Setting this collider to a layer excluded from the Physics3d raycaster seems to have fixed the problem.
I'm currently working on a script that can pick up an item, and drop it with the click of the left mouse button. I'm also planning on addint rotating of an item and some icons to display whenever i do one of those actions.
I'm currently very new to this, so i might be trowing myself out in the depths. But i would like to try.
Here's my code:
public class PickUp : MonoBehaviour {
public Transform onHand;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(Input.GetMouseButton(1)){
this.transform.position = onHand.position;
}
}
void OnMouseDown () {
GetComponent<Rigidbody>().useGravity = false;
this.transform.position = onHand.position;
this.transform.parent = GameObject.Find("Player").transform;
}
void OnMouseUp () {
this.transform.parent = null;
GetComponent<Rigidbody>().useGravity = true;
}
}
So far it kind of works.. I've some trouble picking up my object, it does not always let me. I have to click a couple of times, before it actually gets a hold on the object. When it does, the objects starts flying upwards for some weird reason i do not understand. I still have a hold on it, i can still walk around with it and as soon as i let go it falls down.
Based on the limited amount of data you have shown, I can suggest some common things to check / try. If you update with more details I'll try and help you further.
What value is assigned to your public Transform onHand variable?
Is there a reason why you are doing click detection in two places? Try deleting the lines inside the "Update" method.
The OnMouseDown method should be enough. However, for OnMouseDown to work, your object needs to have a physics collider setup. Check to see if you have a collider and that it's dimensions match what you would expect.
For debug purposes, try setting "isKinematic" to true on your pickup's rigidbody (from the inspector, permanently) this should disable gravity and other forces from moving your pickup object, so you can test out the rest of your code.
Also when you pick it up, set it's transform position to 0,0,0
This should make the object follow the player at the exact center spot of the player object.
Once you verify this works correctly, put features back in and see if any of them break the setup.
Start by setting the position back from 0,0,0 to onHand and then check if the pickup actually appears on the player's hand.
If not, check the value of the onHand variable.
Then you can turn off isKinematic and see if everything is still okay.
As a side note:
You might want to keep using isKinematic instead of disabling gravity. You could set it as kinematic when it's picked up to stop any forces from affecting the pickup's position, while the pickup itself will still have an effect on other rigidbodies.
Then when you drop it on mouse up, just turn off isKinematic again
I am trying to have a block that can only be pushed inside of a rectangular collider. The player has to be able to move through the collider in order to push the block. I have tried to affect the mass upon the block being pushed into the edge collider, the drag, the angular drag, the velocity, isKinematic but nothing will stop the cube from moving when it hits the collider. It is really confusing, any help would really be appreciated...Here is the code:
public class pushBlock2 : MonoBehaviour {
public Rigidbody2D pBlock2;
void OnTriggerEnter2D(Collider2D col)
{
if (col.tag == "edge") {
Debug.Log ("pushblock2 touched edge");
pBlock2.isKinematic = true;
pBlock2.isKinematic = false;
}
}
void OnTriggerStay2D(Collider2D col)
{
if (col.tag == "edge") {
pBlock2.isKinematic = true;
}
}
Why don't you try and create four colliders around the area you want to move your block within? This way you'll have to stop the block from entering those which is much easier task than trying to prevent an item from leaving the collider.
I am pretty sure you will be able to pull this off without any code at all, you just need to setup a couple of static colliders to collide with objects on certain layer and put the cube you wanna move on that layer.
More info on Layer-based collisions can be found here: http://docs.unity3d.com/Manual/LayerBasedCollision.html
The way I understood, you're trying to use the volume defined by a collider as a delimiter for movement. I'm supposing you also desire "realistic" collisions when the object attempts to go outside said volume. That being the case, I'm afraid it is not possible.
The whole physics simulation is made by assuming some rules. Whenever two colliders intersect, the physics follows the rule that two objects should not occupy the same space (just like the real world), and thus it will try to figure out how to separate them again.
You can somewhat work around this by using a set of colliders that defines an hollow object, such as a barrel or box, but its more likely you'll turn off physics simulation for the box and roll up your own algorithm if consistent behavior is needed.
Many things in games are actually "fake" behaviors. Perhaps you can achieve what you want by faking physics or faking collisions?