• 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 Cobradabest · Jul 28, 2013 at 04:37 PM · c#transformposition

How do I make the crosshair go closer/get bigger if an item/wall is close to you?

I'm doing the crosshair by getting a 3D model (that is just a texture on a face) and placing it in front of you, the problem with this is that when I get close to a wall, the crosshair dissapears behind it, as I would've expected, I wanted the crosshair to get bigger/closer if an object goes in front of it. Is there anyway I can do that?

Also, is there anyway I can make the crosshair lock onto an opponent if it spots one, similar to Goldeneye or the Timesplitters games?

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

2 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by TonyLi · Jul 28, 2013 at 07:03 PM

(When you have two questions, please post them separately next time.)

For your first question (crosshair bigger), I recommend displaying the crosshair as an overlaid GUI texture, not a 3D model. You can scale the texture based on the distance. Or, if you stick with the 3D model, you can just move it closer, but what happens when your player is right up against the wall? In the example below, I'll go with your 3D model approach, and assume that the model, named "crosshair," is a child of the camera object.

To figure out how far the wall is, use Physics.Raycast. You'll raycast from the center of the screen. If it hits anything, record the distance. I added two public properties: layerMask, which you set to the layers that you want to detect collisions against, and maxDistance, which is the "default" distance of the 3D model if it hasn't hit anything.

 public LayerMask layerMask;
 public float maxDistance = 20f;
 
 void Update() {
     float distance = maxDistance;
     Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2));
     RaycastHit hit;
     if (Physics.Raycast(ray, out hit, maxDistance, layerMask)) {
         distance = hit.distance;
     }
     crosshair.localPosition = new Vector3(crosshair.localPosition.x, crosshair.localPosition.y, distance);
 }


To make the crosshair lock onto an opponent, you'll want to broaden the scope of your collision detection. You could cast out several rays, or use a SphereCast or a box collider on your player. Let's say you go with the box collider, which is rotated 45 degrees with one of the corners positioned on your player and the rest of the box in front of the player. This forms a 90-degree sweep in front of the player.

As other colliders (enemies) enter the player's box collider, they will trigger OnTriggerEnter or OnColliderEnter messages, depending on whether you set up the box collider as a trigger or not. Record them as they enter or exit. Then decide on which one to target. Finally, run a raycast to the target. If it hits, move the 3D model to the hit point. Otherwise move it to maxDistance (the default distance) in the direction of the ray.

Comment
Add comment · Show 22 · 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 nixcs2512 · Jul 28, 2013 at 09:28 PM 0
Share

I think the Camera Frustum working more perfect in this case than sphere or box collider, can see in this link: http://answers.unity3d.com/questions/142676/camera-fustrum-calculation.html Besides, transform.LookAt is better and easy to understand.

avatar image Cobradabest · Jul 28, 2013 at 10:18 PM 0
Share

I tried out your code, and it's not working, the crosshair still goes through objects if I get close to one, unless I'm right at it, then it zooms right up to you!

I've discovered that in the scene panel, it does zoom in, but it doesn't zoom in enough for you to see it, unless you're close enough, this is very strange...

...and yes, I've set the layer$$anonymous$$ask to my player's. The player collider layer is the same as all the enemies, this is to make sure the enemy AI sees me with their ray/linecasts. So by using layer$$anonymous$$ask, the crosshair ray will ignore the enemies as well and go behind them, which is no good.

Just in case you ask for my code, it's completely identical to the answer's.

avatar image TonyLi · Jul 29, 2013 at 12:22 AM 0
Share

Agreed; sounds like a layer$$anonymous$$ask issue. Your raycast is probably hitting the player collider. A Debug.Log() line would confirm this:

 if (Physics.Raycast(ray, out hit, maxDistance, layer$$anonymous$$ask)) {
     Debug.Log("Hit: " + hit.collider.name);
     distance = hit.distance;
 }

I don't see any reason why you can't have the player and enemies on separate layers to resolve this issue.

(The suggestion by @nixcs2512 will work, too. It just requires a little more code to calculate frustum planes and then test them, rather than letting Physics handle it and just send OnTriggerEnter messages, which I think is easier.)

avatar image Cobradabest · Jul 29, 2013 at 11:46 AM 0
Share

I've tried it, and it doesn't register the player collider, it doesn't actually log anything unless an object is actually in front of it, so it's not a problem with the player collider.

avatar image TonyLi · Jul 29, 2013 at 01:06 PM 1
Share

You may need to set the crosshair model's distance to something just a little closer than the raycast hit distance.

Or, if you draw a texture in OnGUI() ins$$anonymous$$d of using a 3D model, you can bypass the whole issue. Just replace the whole 3D model thing with something like:

 void OnGUI() {
     float scale = <compute some scaling factor based on raycast distance>
     float size = textureSize * scale;
     float halfSize = size / 2;
     float centerX = Screen.width / 2;
     float centerY = screen.height / 2;
     Rect rect = new Rect(centerX - halfSize, centerY - halfSize, size, size);
     GUI.DrawTexture(rect, myCrosshairTexture);
 }
Show more comments
avatar image
0

Answer by rowdyp · Jul 31, 2013 at 11:28 PM

putting the cross hair as a GUI will still add all the functionality desired, but keep it in front of the environment.

Comment
Add comment · Show 3 · 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 Cobradabest · Jul 31, 2013 at 11:39 PM 0
Share

Well, I actually have a reason for making it the way i am, I want to make it so that when I turn, the crosshair moves slightly in the direction you're turning (and I already a script to do that), and the guns have been programmed to constantly looking at it, so as the crosshair moves, the guns also turn, giving a sort of illusion of the player turning, similar to how it was in FPS games such as Goldeneye and the Timesplitters Series. It also guarentees that the gun will shoot where the crosshair is without fail.

Is it possible to do the same thing using a GUI crosshair?

avatar image rowdyp · Jul 31, 2013 at 11:42 PM 0
Share

well you can apply an offset of the texture with the movement of the character or weapon.

avatar image TonyLi · Aug 01, 2013 at 12:49 AM 0
Share

You can still use the same raycast code from my first post, where I actually recommended using a GUI texture because as @rowdyp said it's easier to guarantee that it will always be in front. You can scale the texture by distance, and offset it by rotational movement.

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.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

18 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

Related Questions

C# GUI.Button Transform.Position 1 Answer

How do I check if an Object isn't moving? (C#) 1 Answer

C# GameObjectList not Setting Parent 0 Answers

Freeze transform.rotation.x 1 Answer

C# The call is ambiguous between the following methods or properties 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