Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by Badgerfish · Sep 29, 2015 at 02:06 AM · raycastingmeshcolliderkinematic

How to push a kinematic object so it does not go through a wall?

Hi, I'm working on spawning game objects and placing them in the world by using raycasing. I essentially get an object from a list in the GUI, this object spawns attached to the mouse pointer, when I click I can place the object and the set it's rotation with another click.

The problem is the object has a radius, and when raycasting the user is able to place objects 'on' walls, because I'm setting the kinematic object's transform.position.

Is there any way to push off from walls so the object doesn't go through them and can't be glued on to walls only flat (floor-like) surfaces? Ideally by the radius of the object.

alt text

I'm using kinematic objects because the game I'm making uses a really simple system to move around based on mouse-click (raycast) locations. But I can't have my guys sticking half way through a wall. The object has a kinematic rigidbody and a convex trigger mesh collider in the shape of a cylinder.

Here's what my raycaster code looks like so far:

 //This is the object to be spawned
     public GameObject objectToSpawn;
     public GameObject facingProjector;
 
     public float rotationSpeed = 10.0f;
 
     public bool debug = false;
 
     //This is the actual camera we reference in the update loop, set in Start()
     private Camera _camera;
     //to check if the object is set, otherwise will not activate
     private bool objectSelected = false;
     private bool locationSet = false;
     private bool rotationSet = false;
     private bool projectorActive = false;
 
     private Quaternion projectorDefaultFacing;
 
     private int unitLayer;
 
     private float clearanceRadius = 0.0f;
     
     void Start()
     {
         _camera = Camera.main;
         projectorDefaultFacing = Quaternion.identity;
         //GameObject instance = Instantiate (facingProjector, Vector3.zero, projectorDefaultFacing) as GameObject;
         //facingProjector = instance;
         facingProjector.SetActive (false);
         unitLayer = LayerMask.NameToLayer("Unit");
     }
     
     // Update is called once per frame
     void Update () {
         Ray ray;
         RaycastHit hit;
 
         //If there's no object selected any click will attach the object to the mouse pointer to edit it's location and rotation
         //If the object is a trooper, or Unit, we have to watch for clearance radius so we can't spawn the object in walls
         if (!objectSelected) {
             ray = _camera.ScreenPointToRay(Input.mousePosition); 
             
             //If we hit...
             if(Physics.Raycast (ray, out hit, 100) && !UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject())
             {
                 if(hit.transform.gameObject.tag != "Terrain"){
                     if(debug)Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.cyan);
                     if(Input.GetMouseButton(0)){
                         if(debug)Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.green);
                         objectToSpawn = hit.transform.parent.transform.gameObject;
                         objectSelected = true;
                         if(objectToSpawn.tag == "Unit"){
                             clearanceRadius = objectToSpawn.GetComponent<UnitInfo>().clearanceRadius;
                         }
                     }    
                 }else{
                     if(debug)Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.magenta);
                 }
             }
         }
 
         //Here object is selected, and is attached to the mouse until the button is released or a click happens if it's a new object
         //When the mouseUp event happens the object's location is set
         if (objectSelected && !locationSet && !rotationSet) {
 
             //Set up our ray from screen to scene
             ray = _camera.ScreenPointToRay(Input.mousePosition); 
 
             //If we hit...
             if(Physics.Raycast (ray, out hit, 100, unitLayer) && !UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject())
             {
                 if(debug)Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.yellow);
                 //if the hit was registered on terrain, we can't place things on top of non-terrain
                 if(hit.transform.gameObject.tag == "Terrain"){
                     objectToSpawn.transform.position = hit.point;
                     if(Input.GetMouseButtonUp(0)){
                         SetLocation();
                     }
                 }
             }
         }
         //Object has a desired location, now rotation is set to follow the mouse on X/Z plane
         //When a click happens it will set the rotation and un-set the object
         if (objectSelected && locationSet && !rotationSet) {
             if(projectorActive == false){
                 if(debug)Debug.Log("Activating Projector!");
                 facingProjector.SetActive(true);
                 projectorActive = true;
                 facingProjector.transform.position = objectToSpawn.transform.position;
                 facingProjector.transform.rotation = objectToSpawn.transform.rotation;
             }
             //active rotation setting loop
             SetRotation();
         }
         //Once location and rotation are set, the system resets, because there's no object
         if (locationSet && rotationSet) {
             objectSelected = false;
             locationSet = false;
             rotationSet = false;
         }
     }
 
     public void SpawnThisObject(GameObject spawnableObject){
         objectToSpawn = Instantiate(spawnableObject, Vector3.zero, Quaternion.identity) as GameObject;
         objectSelected = true;
         if(debug)Debug.Log ("Object Set!");
     }
 
     public void SetLocation(){
         Ray ray;
         RaycastHit hit;
         //Set up our ray from screen to scene
         ray = _camera.ScreenPointToRay(Input.mousePosition); 
         
         int unitLayer = LayerMask.NameToLayer("Unit");
         if (Physics.Raycast (ray, out hit, 100, unitLayer) && !UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject ()) {
 
             //if the hit was registered on terrain, we can't place things on top of non-terrain
             if(hit.transform.gameObject.tag == "Terrain"){
                 if(debug)Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.green);
                 //check surrounding area around object to make sure it fits?
                 objectToSpawn.transform.position = hit.point;
                 locationSet = true;
                 if(debug)Debug.Log ("Location Set!");
             }
         }
     }
 
     public void SetRotation(){
 
         Ray ray;
         RaycastHit hit;
         //Set up our ray from screen to scene
         ray = _camera.ScreenPointToRay(Input.mousePosition); 
 
         if (Physics.Raycast (ray, out hit, 100, unitLayer) && !UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject ()) {
             if((hit.point - objectToSpawn.transform.position) != Vector3.zero){
                 //rotation leveling, so object spawned doesn't look 'up' or 'down' only side to side
                 Vector3 hitPos = new Vector3(hit.point.x, 0, hit.point.z);
                 Vector3 objectPos = new Vector3(objectToSpawn.transform.position.x, 0, objectToSpawn.transform.position.z);
                 Quaternion targetRotation = Quaternion.LookRotation(hitPos - objectPos);
                 objectToSpawn.transform.rotation = Quaternion.Slerp(objectToSpawn.transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
                 facingProjector.transform.rotation = Quaternion.Slerp(facingProjector.transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
             }
         }
         if (Input.GetKeyDown(KeyCode.Return) || Input.GetMouseButtonDown(0)){
             if(debug)Debug.Log("Rotation Set!");
             rotationSet = true;
             facingProjector.transform.rotation = projectorDefaultFacing;
             facingProjector.SetActive(false);
             projectorActive = false;
         }
     }

deploy1.png (180.9 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by hexagonius · Sep 29, 2015 at 01:53 PM

the hit point holds info about the surface normal. add the normal times radius to the hit point. then, raycast again,down. that's your spawn point. gets tricky in corners though. depending on existing corner angles you could check all directions, or against each hit point... depends on complexity.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Badgerfish · Sep 29, 2015 at 02:58 PM 0
Share

Yeah, it totally dawned on me last night "O$$anonymous$$G NOR$$anonymous$$ALS!". Then I thought, well how would I move the radius and suddenly... "NOR$$anonymous$$ALS ARE UNITARY".

I still haven't fixed the problem, but I have a good direction to work in. Thanks.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

29 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Does Unity support raycasting to meshcolliders from FBX files ? 0 Answers

How to make a non-convex meshed object affected by physics(non-kinematic) 0 Answers

Obtain a Transform using RayCastAll without a Collision (ie a point in space) 2 Answers

Checking if the reflected angle is too sharp 0 Answers

Physics.Raycast and Debug.DrawRay not working with Google Cardboard / Google VR? Or because within a Delegate? 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges