Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Cappa

#1
Scripting / Ejecutar Align with view desde script
Abril 06, 2019, 09:35:59 PM
Cita de: lightbug date=1554238898El método "AlignAuxiliaryCameraWithViewport" está haciendo cosas como:
   
   

GameObject[] newSelection = new GameObject[1] { auxiliaryCamera.gameObject };

   
      probablemente estés generando cuadro a cuadro más basura que homero simpson como alcalde https://docs.unity3d.com/ScriptReference/EditorWindow.OnSelectionChange.html )una vez ocurre esto moves la cámara (que previamente catcheaste) a la posición correcta.
   
   
      Y el AlignObjectWithView (dedicado a la mainCamera) lo unico que hace es algo así:
   
   

if( viewportCamera == null )
viewportCamera = SceneView.GetAllSceneCameras()[0];
   
if( mainCamera == null )
mainCamera = Camera.main;            
   
mainCamera.transform.position = viewportCamera.transform.position;
mainCamera.transform.rotation = viewportCamera.transform.rotation;

   
      En tiempo real funciona, aunque no recuerdo si lo usé en un OnSceneGUI, Update (con [ExecuteInEditMode] ) o parecido, la verdad ya borré todo xD, osea sería una variante en tiempo real de "AlignObjectWithView", pero no es lo mismo que lo que aparece en el video.
   


Muchas gracias lightbug, en cuanto vuelva a tener tiempo para ponerme con esto reviso y pruebo bien todo lo que me comentaste a ver si puedo prescindir de EditorApplication.ExecuteMenuItem( "GameObject/Align With View" ); ya que utilizar ese método es lo que me quita todo el control que debería tener sobre la funcionalidad.

Igual, como ya coment'e en el mensaje anterior, resulta que me anda perfectamente bien y fluido en la versión que mostré, descubrí que es en un proyecto concretamente que se jode la performance!


Gracias! Saludos!


Cappa
#2
Yo tampoco he usado MoveTowards. Tengo un script muy similar que hice hace un tiempo, le cambié los nombres y le hice una pequeña adaptación para lo que buscas:

Quizá es demasiado complejo para lo que necesitas ya que hago uso de curvas, pero está bastante claro el tema del Lerp en vectores y cuaterniones.
 

using UnityEngine;
public class PointOfViewHandler: MonoBehaviour
{
    [Header("")]
#pragma warning disable IDE0044 // Add readonly modifier
    [SerializeField] private new Transform camera;
    [Header("References of points of view")]
    // Assigned in inspector
    [SerializeField] private Transform firstPerson = null;
    [SerializeField] private Transform thirdPerson = null;
    public enum PointsOfView
    {
        FIRST_PERSON,
        THIRD_PERSON
    }
    [Header("")]
    [SerializeField] private PointsOfView currentPointOfView = PointsOfView.FIRST_PERSON;
    [Header("Lerp parameters")]
    [SerializeField] private float lerpTime = 25;
    [SerializeField] private AnimationCurve smoothCurve = new AnimationCurve( new Keyframe[]{ new Keyframe( 0, 0 ) , new Keyframe( 1, 1 ) } );
#pragma warning restore IDE0044 // Add readonly modifier
    private float currentLerpTime;
    private Transform target;
    private void Awake()
    {
        GetCamera();
        SetInitialPosition();
    }
    private void GetCamera()
    {
        if ( camera == null )
            try { camera = Camera.main.transform; }
            catch
            {
                try { camera = FindObjectOfType<Camera>().transform; }
                catch { Debug.LogError( "Assign a camera" ); }
            }
        camera.transform.SetParent( transform );
        camera.transform.localPosition = Vector3.zero;
        camera.transform.localRotation = Quaternion.identity;
    }
    private void SetInitialPosition()
    {
        if ( firstPerson == null || thirdPerson == null )
        {
            Debug.LogError( "Point of view not assigned" );
            return;
        }
        switch ( currentPointOfView )
        {
            case PointsOfView.FIRST_PERSON:
                transform.position = firstPerson.position;
                transform.rotation = firstPerson.rotation;
                break;
            case PointsOfView.THIRD_PERSON:
                transform.position = thirdPerson.position;
                transform.rotation = thirdPerson.rotation;
                break;
        }
    }
    private void Update()
    {
        if ( Input.GetKeyDown( KeyCode.V ) )
            ChangePoint();
        if ( target == null ) return;
        if ( Vector3.Distance( transform.position, target.position ) < 0.01f )
        {
            transform.position = target.position;
        }
        Movement();
    }
    private void Movement()
    {
        if ( target == null ) return;
        currentLerpTime += Time.deltaTime;
        float percent = smoothCurve.Evaluate(currentLerpTime / lerpTime);
        Translate( percent );
        Rotate( percent );
    }
    private void Translate( float percent ) => transform.position = Vector3.Lerp( transform.position, target.position, percent );
    private void Rotate( float percent ) => transform.rotation = Quaternion.Lerp( transform.rotation, target.rotation, percent );
    private void ChangePoint()
    {
        currentLerpTime = 0f;
        currentPointOfView = currentPointOfView == PointsOfView.FIRST_PERSON ? PointsOfView.THIRD_PERSON : PointsOfView.FIRST_PERSON;
        switch ( currentPointOfView )
        {
            case PointsOfView.FIRST_PERSON:
                target = firstPerson;
                break;
            case PointsOfView.THIRD_PERSON:
                target = thirdPerson;
                break;
        }
    }
}

 
Simplemente creás un objeto en la escena y le añadís este componente.

Para cambiar puntos de vista del player te recomiendo una curva simple (probablemente la que seteo por defecto) y una velocidad bastante alta (Lerp Time bajo), esto lo configurás en el inspector.

Si no asignás la cámara, el script tomará la primera que encuentre en la jerarquía de la escena.
#3
Scripting / Ejecutar Align with view desde script
Abril 02, 2019, 07:56:43 PM
Alguien que lo probo me esta diciendo que lo ve fluido, entonces cree un proyecto nuevo para probar y funciona bien... no se que estará pasando.


Creo que se puede dar por resuelto el thread.
#4
Scripting / Ejecutar Align with view desde script
Abril 02, 2019, 07:05:35 PM
Bueno, lo logré pero por alguna razón no funciona de forma fluida, dejo el código fuente por si a alguien le interesa encontrarle la vuelta que le falta.

 
 

using Unit***itor;
using UnityEngine;
public class ViewportSceneCameraManager: EditorWindow
{
    private static Camera auxiliaryCamera;
    private RenderTexture renderTexture;
    [MenuItem( "Test/Create viewport scene camera" )]
    private static void Init()
    {
        EditorWindow editorWindow = GetWindow( typeof( ViewportSceneCameraManager ) );
        editorWindow.autoRepaintOnSceneChange = true;
        editorWindow.Show();
    }
    public void Awake()
    {
        renderTexture = new RenderTexture( (int)position.width,
            (int)position.height,
            (int)RenderTextureFormat.ARGB32 );
    }
    public void OnEnable()
    {
        CreateAuxiliaryCamera();
    }
    public void Update()
    {
        AlignAuxiliaryCameraWithViewport();
        if ( auxiliaryCamera != null )
        {
            auxiliaryCamera.targetTexture = renderTexture;
            auxiliaryCamera.Render();
            auxiliaryCamera.targetTexture = null;
        }
        if ( renderTexture.width != position.width ||
            renderTexture.height != position.height )
            renderTexture = new RenderTexture( (int)position.width,
                (int)position.height,
                (int)RenderTextureFormat.ARGB32 );
    }
    private void OnGUI()
    {
        if ( renderTexture )
            GUI.DrawTexture( new Rect( 0.0f, 0.0f, position.width, position.height ), renderTexture );
    }
    private static void CreateAuxiliaryCamera()
    {
        GameObject camObj = Instantiate(Camera.main.gameObject);
        camObj.name = "Debug Camera";
        Component[] camComponents = camObj.GetComponents<Component>();
        for ( int i = 0; i < camComponents.Length; i++ )
        {
            if ( camComponents[i].GetType() != typeof( Camera ) && camComponents[i].GetType() != typeof( Transform ) )
            {
                if ( BL.DebugManager.DebugManager.isEditorMode )
                    DestroyImmediate( camComponents[i] );
                else
                    Destroy( camComponents[i] );
            }
        }
        auxiliaryCamera = camObj.GetComponent<Camera>();
        auxiliaryCamera.clearFlags = CameraClearFlags.SolidColor;
        auxiliaryCamera.depth = -100;
    }
    private static void AlignAuxiliaryCameraWithViewport()
    {
        Object[] backupSelections = null;
        if ( Selection.objects != null )
            backupSelections = Selection.objects;
        GameObject[] newSelection = new GameObject[1] { auxiliaryCamera.gameObject };
        Selection.objects = newSelection;
        EditorApplication.ExecuteMenuItem( "GameObject/Align With View" );
        if ( backupSelections == null )
            Selection.objects = new Object[0];
        Selection.objects = backupSelections;
    }
    private void OnDestroy()
    {
        if ( isEditorMode )
            DestroyImmediate( auxiliaryCamera.gameObject );
        else
            Destroy( auxiliaryCamera.gameObject );
    }
    public static bool isEditor => Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.LinuxEditor;
    public static bool isEditorMode => isEditor && !Application.isPlaying;
}

 
Este script crea una versión modificada de Camara.Main.

Muestra lo que esa cámara ve en una ventana nueva de unity.

Cuando el usuario se "mueve" en el viewport, esta cámara hace exactamente lo mismo.

Ejemplo de utilidad:
 


   
tart=60&feature=oembed" width="480">

 
A diferencia de lo que se ve en el video, mi sistema tiene su propia cámara y su propia ventana (al cerrar la ventana se borra la cámara auxiliar).

Problemas:
 
Horrible performance en el Update, todavía no identifico que es exactamente.
 
 
 
ViewportSceneCameraManager.cs
 
#5
Scripting / Ejecutar Align with view desde script
Abril 01, 2019, 10:13:02 PM
Cita de: pioj date=1554147631Lo más parecido que he encontrado es ésto: 
   
   
      https://answers.unity.com/questions/26606/align-with-view-programmatically.html
   
   
       
   


Ya anduve por ahí, en lo practico no pude lograr nada con lo que se comenta.


Encontré una manera de ejecutar acciones del menú de Unity (https://docs.unity3d.com/ScriptReference/EditorApplication.ExecuteMenuItem.html), pero lamentablemente la acción que necesito depende de una selección manual previa de un objeto de la escena.


Entonces estuve haciendo unas pruebas locas
 

[MenuItem( "VisualDebugging/Align Camera With Viewport %Q" )]
    public static void AlignCameraWithView()
    {
        Object[] aux = Selection.objects;
        GameObject[] newSelection = new GameObject[1] { FindObjectOfType<Camera>().gameObject };
        Selection.objects = newSelection;
        EditorApplication.ExecuteMenuItem( "GameObject/Align With View" );
        Selection.objects = aux;
    }

 
Esto funciona, pero no es nada lindo, técnicamente lo que hace ese método es buscar la cámara de la escena y decirle a Unity que se trata de un GameObject seleccionado por el usuario.

Luego ejecuto el mismo "Align With View" de la interfaz del engine, y para no perder la selección que pudo haber hecho el usuario antes de ejecutar este método, restablezco Selection.objects usando la variable auxiliar (aux).


Lo se, es horrible, sigo haciendo pruebas e investigando...

EDIT:


Y por cierto, el objetivo final es que esto se haga en bucle durante un tiempo en editor mode, de manera que la cámara del juego copie lo que el usuario hace con el viewport.
#6
Scripting / Ejecutar Align with view desde script
Abril 01, 2019, 08:15:27 PM
Necesito que una cámara instanciada en la escena se alinee con la vista del viewport mediante un script que se ejecuta en editor mode.
Ya existe una acción que logra esto, se encuentra en Gameobject -> Align With View cuando se tiene un objeto de escena seleccionado.
 
Es posible realizar esa instrucción por script? sino, que alternativas tengo?

 
 
#7
Hola gente!

Soy Cappa, me dedico al desarrollo de videojuegos en Unity3D.
 
:D