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 Condore · Oct 06, 2012 at 03:08 AM · cameraenemycombatfovlockon

FOV sensitive Lock-on?

Hey guys,

I was just wondering how I could make a lock on system FOV sensitive? Meaning that if I want to lock onto something it has to be within the FOV of the camera.

So if anything is outside of the FOV it will not target it.

I'm trying to refine the lock-on system I have in order to make it more efficient. I was also wondering how I can set a maximum lock on distance so that the enemy must be within a certain distance to be targetable and they must be actually in the FOV of the camera.

Here's my targetting code so far, for our lock on system.

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class Targetting : MonoBehaviour 
 {
     GameObject[] enemies;
     public Transform selectedTarget;
     public Transform nearestEnemy;
     public Vector3 enemyCenter;
     
     public float minimumTargetDistance = 100.0f;
     
     private float lastFrameLockOn;
     
     GameObject[] lockOnTransforms;
 
     //Transform of the UI element
     public Transform lockOn;
     
     // Use this for initialization
     void Start () 
     {    
         lastFrameLockOn = Input.GetAxis("LockOn");
         selectedTarget = null;
     }
     
     // Update is called once per frame
     void Update () 
     {
         if(Input.GetAxis("LockOn") > 0.5f )
         {
             if(Input.GetAxis("LockOn") > 0.5f && lastFrameLockOn < 0.5f)
             {
                 targetCloseEnemies();
             }
             
             if(selectedTarget)
             {
                 transform.LookAt(selectedTarget.position);
             }
             
             if(nearestEnemy)
             {
                 if(selectedTarget != nearestEnemy)
                 {
                     TargetEnemy(nearestEnemy);
                 }
             }
             
         }
         if(Input.GetAxis("LockOn") <= 0.5f)
         {
             selectedTarget = null;
             nearestEnemy = null;
             enemyCenter = Vector3.zero;
             DestroyLockOns();
         }
         
         lastFrameLockOn = Input.GetAxis("LockOn");
     }
     
     private void targetCloseEnemies()
     {
         // Find all enemies within the scene and add them to a list
         enemies = GameObject.FindGameObjectsWithTag("Enemy");
         
         //Add enemies that are within range to a new list of targetable enemies
         foreach(GameObject enemy in enemies) // list of all enemies
         {
             float enemyDistance = Vector3.Distance(transform.position, enemy.transform.position); // distance of new enemy to player
             if(enemyDistance <= minimumTargetDistance) // checks if the new enemy is close enough to target
             {
                 
                 if(nearestEnemy)
                 {
                     if(enemyDistance < Vector3.Distance(transform.position, nearestEnemy.position )) // checks if new enemy is closer than existing enemy
                     {
                         nearestEnemy = enemy.transform;
                     }
                 }
                 else
                 {
                     
                     nearestEnemy = enemy.transform; // if the nearest enemy doesn't exist, the new enemy is assigned to nearestenemy
                 }
             }
         }
         
         if(nearestEnemy)
         {
             Bounds bounds = new Bounds (nearestEnemy.transform.position, Vector3.one);
 
             Renderer[] renderers = nearestEnemy.GetComponentsInChildren<MeshRenderer>();
         
             foreach (Renderer renderer in renderers)
         
             {
                 bounds.Encapsulate (renderer.bounds);
             }
             
             renderers = nearestEnemy.GetComponentsInChildren<SkinnedMeshRenderer>();
         
             foreach (Renderer renderer in renderers)
             {
                 bounds.Encapsulate (renderer.bounds);
             }
             
             Debug.Log ("bounds center: "+bounds.center);
             
             enemyCenter = bounds.center;
             
         }
     }
     
     public void TargetEnemy(Transform target)
     {    
         
         selectedTarget = target;
         
         DestroyLockOns();
             
         if (selectedTarget)
         {
             Transform lockOnClone = Instantiate(lockOn, Vector3.zero, Quaternion.identity) as Transform;
             lockOnClone.parent = selectedTarget.transform;
             lockOnClone.position = enemyCenter;
         }
     }
     
     void DestroyLockOns()
     {
         lockOnTransforms = GameObject.FindGameObjectsWithTag("LockOn");
         //Debug.Log ("found " + lockOnTransforms.Length + " lockons");
         foreach(GameObject lockOnTransform in lockOnTransforms)
         {
             Debug.Log ("Destroying lockon");
             Destroy(lockOnTransform);
         }
     }
 }
Comment
Add comment · Show 7
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 Condore · Oct 07, 2012 at 12:27 AM 0
Share

Also, wondering if I can use the OnBecameVisible() function to possibly do this.

I don't have enough coding experience to figure this out on my own. :S

avatar image K4g3 · Oct 07, 2012 at 04:42 AM 1
Share

would it be possible to use raycast to accomplish both of these? for example, once a potential lockon target is acquired, a raycast is sent from the shooter in the direction of the target with the maximum distance requirement, and if the raycast doesnt hit anything between the shooter and the target (so a clear LoS), the lockon continues as normal.

avatar image Condore · Oct 07, 2012 at 08:41 PM 0
Share

I could try that, the only problem with that is I don't want the player to be able to lock onto a target if they are outside of the camera's FOV.

The Raycast would work for setting a maximum lock on distance though. I'll try giving that a shot right now.

Do you have any way that I might be able to make it FOV sensitive?

avatar image K4g3 · Oct 07, 2012 at 09:52 PM 1
Share

I see. I'm no pro myself, but it seems like OnBecameVisible would be your best bet.
In the OnBecameVisible function for the targets, you could put your raycast script to see if it were in range, and if it was you could call your lockon function. But things usually seem simpler in my head than they are in code...

avatar image K4g3 · Oct 07, 2012 at 09:57 PM 1
Share

Or in the targets OnBecameVisible script, it calls a function in your shooting objects script that has both the raycast distance check and lockon code

Show more comments

1 Reply

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

Answer by refardeon · Oct 10, 2012 at 07:35 PM

Hey there,

there is a neat way to do this using Camera.WorldToViewportPoint - http://docs.unity3d.com/Documentation/ScriptReference/Camera.WorldToViewportPoint.html

That returns a value between (0,0) and (1,1) when an object is somewhere on screen. If the object is outside, the values will be outside this range, see the example code in the reference.

This measures from the center of an object, not the bounds; so it might be necessary to include some tolerance in the check (maybe something like (0.05, 0.05) to (0.95, 0.95), that way the object has to be further on screen. It's also possible to use something like (-0.05, -0.05) to (1.05, 1.05), that way you'd also include objects that are somewhat off screen. Try and see what feels fun :)

The method is not too expensive, but as you'd have to call it every frame for every possible target: Try and restrict the amount of objects you check with this, maybe only include enemies that'd be in range. In any case, cache the reference to the camera you're using for this. In my game, that brought a significant boost in performance.

Happy coding!

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

11 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

Related Questions

Camera movement in a 2D? (like angry birds) 1 Answer

Unique names for Instantiated prefabs? 1 Answer

Knockback using Navmesh 1 Answer

Orthographic camera "cutting off" part of the frame 2 Answers

Minimap camera display size. 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