Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 /
avatar image
0
Question by frankbradshaw · Feb 12, 2015 at 12:39 AM · c#raycast

Ray cast an area instead of a line

Hi everyone - I am reasonably new to Unity and C# but I'm finding my feet on an e-learning demo and trying to pack in as many self-objectives to learn on it to get to grips with both language and program.

The aim of the demo is to walk around and click on various items to carry out tasks. Currently I have the following code to raycast out to the mouse pointer when it is clicked and detect which object was clicked:

  // test on every update if mouse has been left clicked on a gameObject
 if (Input.GetMouseButtonDown(0)){ // if left button pressed...
 Debug.Log("Main camera pixelWidth = "+Camera.main.pixelWidth);
 Debug.Log("Main camera pixelHeight = "+Camera.main.pixelHeight);
 
 RaycastHit hit;
 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
 float distance = (this.InteractionDistance < 0) ? Mathf.Infinity : this.InteractionDistance;
    if (Physics.Raycast(ray, out hit, distance)){
       TransformClicked(hit.transform);
     }
 }

And this works. A little awkward because the user has to reposition the mouse to click, but it works.

So I decided after some play testing to change the mouseclick to a button press, using E, like on many FPS like Half Life.

 if(Input.GetKeyDown("e")){ // use e click interact, more Half Life like
 Debug.Log("Main camera pixelWidth = "+Camera.main.pixelWidth);
 Debug.Log("Main camera pixelHeight = "+Camera.main.pixelHeight);
 
 RaycastHit hit;
 Ray ray = Camera.main.ScreenPointToRay(new Vector2(Screen.width/2, Screen.height/2)); //ray to centre of the screen
 float distance = (this.InteractionDistance < 0) ? Mathf.Infinity : this.InteractionDistance;
     if (Physics.Raycast(ray, out hit, distance)){
         TransformClicked(hit.transform);
     }
 }

  

And again this works great - a ray is sent to the centre of of the screen but for me this is way to precise. What would be perfect would be if you could resize the size of the ray so instead of being a pixel or whatever it is, it was 50 x 50 or something.

Not really knowing if this was possible, I've searched online and set out to determine an area at the centre of the screen that is the "ray area" - if anything inside this area hits a gameobject then run the TransformClicked method.

So far I have worked out 4 Vector2 points on screen using

 private void CreateClickPoint()
     {
         //work out center points for screen x and y
         centerScreenX = Screen.width/2;
         centerScreenY = Screen.height/2;

         //work out a clickable area
         xTopLeft = new Vector2(centerScreenX-30, centerScreenY-30); Debug.Log("xTopLeft = "+xTopLeft);
         xTopRight = new Vector2(centerScreenX+30, centerScreenY-30); Debug.Log("xTopRight = "+xTopRight);
         xBottomLeft = new Vector2(centerScreenX-30, centerScreenY+30); Debug.Log("xBottomLeft = "+xBottomLeft);
         xBottomRight = new Vector2(centerScreenX+30, centerScreenY+30); Debug.Log("xBottomRight ="+xBottomRight);
     }

And that's it. Is there anyway for me to use these 4 points and say When E is pressed, determine using rays if there is a game object within the area of these 4 points? Or have I missed something that is built in that is extremely obvious?

cheers for any help

Frank

Comment
Add comment · Show 3
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 frankbradshaw · Feb 11, 2015 at 04:33 PM 0
Share

Quick update - I made two changes; a bit more research (oops) and I found out about the SphereCast which does what I want in principle. http://answers.unity3d.com/questions/447305/c-more-accurate-or-larger-raycast.html and http://docs.unity3d.com/ScriptReference/Physics.SphereCast.html

I added a new class because my class $$anonymous$$ainGameLogic isn't on my gamecontroller -

public class RayCastSphere : $$anonymous$$onoBehaviour {

 $$anonymous$$ainGameLogic $$anonymous$$GLConnector;
     
     
 void Awake()
 {
         
 }
     
 void Start()
 {
     $$anonymous$$GLConnector = new $$anonymous$$ainGameLogic();
 }
     
 void Update()
 {
         if(Input.Get$$anonymous$$eyDown("e")) {
         RaycastHit sphereHit;
         CharacterController charCtrl = GetComponent<CharacterController>();
         Vector3 p1 = transform.position + charCtrl.center;
         if(Physics.SphereCast(p1,2,transform.forward,out sphereHit, 10))
             $$anonymous$$GLConnector.TransformClicked(sphereHit.transform);
         }
 }
     

}

But still no joy. Nothing happens when I press E, but no errors either. Any thoughts before I start to debug.log the lot?

cheers :)

Frank

avatar image lordlycastle · Feb 12, 2015 at 03:12 AM 0
Share

Firstly, if the gameObject user wants to click, is big enough for the user to click, then ray should hit just fine, make sure that object's layer mask is not set to IgnoresRaycasts. If you really need to fire multiple rays you can use a for loop which alters the direction vector by, let's say, ±10° and use break to exit the loop if it does hit a collider. (You could use another for loop inside that if you wanna alter the direction along two axis)

Secondly, you are also using this.InteractionDistance in you code, would be nice if you could also provide the function.

I don't think there is a way to cast the ray over an area because then it might hit two objects.

avatar image Owen-Reynolds · Feb 12, 2015 at 05:16 AM 0
Share

Ray/Sphere/Capsule casts are tricky. An odd function (return by value AND ref,) you can't see them, lots of overloads, need to understand Vector math and local/global.

If everything else fails, just set up a simple scene with some big fat walls and a raycasting empty. $$anonymous$$ove and spin it by hand (while running) to see when/what if hits.

1 Reply

· Add your reply
  • Sort: 
avatar image
2

Answer by incorrect · Feb 12, 2015 at 05:41 AM

Like this?

 using UnityEngine;
 using System.Collections;
 
 public class SphereCaster : MonoBehaviour {
 
     public float castingRadius = 2f;
     public float castingDistance = 10f;
 
     void Update()
     {
         if(Input.GetKeyDown(KeyCode.E))
         {
             Debug.Log ("OMG! SO SPHERE! MUCH CASTING!");
             RaycastHit sphereHit;
             Ray ray = Camera.main.ScreenPointToRay(new Vector3(Camera.main.pixelWidth/2f, Camera.main.pixelHeight/2f, 0f));
 
             if(Physics.SphereCast(ray, castingRadius, out sphereHit, castingDistance))
             {
                 Debug.Log("WOW! SOMETHING HIT!");
                 MGLConnector.TransformClicked(sphereHit.transform);
             }
         }
     }
 }
 

Comment
Add comment · 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

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Change Transparency 1 Answer

How to Find Owner of a Trigger? 1 Answer

Raycast from camera not hitting Terrain 1 Answer


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