Прикрепите камеру к объекту сценария в единстве

Я только что написал paisa.js для этого, и он правильно обрабатывает лакхи и кроры, может проверить это. Ядро выглядит примерно так:

const regulars = [
  {
    1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine'
  },
  {
    2: 'twenty', 3: 'thirty', 4: 'forty', 5: 'fifty', 6: 'sixty', 7: 'seventy', 8: 'eighty', 9: 'ninety'
  }
]

const exceptions = {
  10: 'ten',
  11: 'eleven',
  12: 'twelve',
  13: 'thirteen',
  14: 'fourteen',
  15: 'fifteen',
  16: 'sixteen',
  17: 'seventeen',
  18: 'eighteen',
  19: 'nineteen'
}

const partInWords = (part) => {
  if (parseInt(part) === 0) return
  const digits = part.split('')
  const words = []
  if (digits.length === 3) {
    words.push([regulars[0][digits.shift()], 'hundred'].join(' '))
  }
  if (exceptions[digits.join('')]) {
    words.push(exceptions[digits.join('')])
  } else {
    words.push(digits.reverse().reduce((memo, el, i) => {
      memo.unshift(regulars[i][el])
      return memo
    }, []).filter(w => w).join(' '))
  }
  return words.filter(w => w.trim().length).join(' and ')
}

3
задан Thrindil 17 January 2019 в 06:41
поделиться

1 ответ

Вы не можете не напрямую прикреплять ссылки на сцены к ScriptableObject или к любым активам.

Но вы можете пойти другим путем: дать камере ссылку ScriptableObject и заставить ее указать свою собственную ссылку на это ScriptableObject:

// This attribute makes this classes messages be executed also in editmode
// (= also of not in playmode)
[ExecuteInEditModo]

// Assure there is a Camera component
[RequireComponent(typeof(Camera))]
public class CameraSetter : MonoBehaviour
{
    [SerializeField] private MainCamera mainCameraAsset;

    // Called on initialize
    // With [ExecuteInEditModo] also called on recompile
    private void Awake ()
    {
        mainCameraAsset.Camera = GetComponent<Camera>();
    }
}

И сослаться на свой MainCamera ] экземпляр в mainCameraAsset.


Есть ли причина, по которой вы не используете Camera.main вместо ScriptableObject?


Карта для разных сцен

В случае, если вы хотите заархивировать что-то вроде «актива менеджера», хранящего разные ссылки Camera для каждой сцены в соответствии с запросом в комментариях (надеюсь, я вас правильно понял), я бы изменил ваш MainCamera на что-то вроде

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/MainCamera", 
order = 1)]
public class MainCamera : ScriptableObject
{
    public List<SceneCameraPair> SceneCameraPairs = new List<SceneCameraPair>();

    public Dictionary<string, Camera> sceneToCamera = new Dictionary<string, Camera>();

    public void AddPair(SceneCameraPair pair)
    {
        if(SceneCameraPairs.Contains(pair)) return;

        SceneCameraPairs.Add(pair);
        sceneToCamera[pair.scene.path] = pair.camera;
    }

    public void ResetPairs()
    {
        SceneCameraPairs.Clear();
        sceneToCamera.Clear();
    }
}

[System.Serializable]
public class SceneCameraPair
{
    public Scene scene;
    public Camera camera;
}

и в установщике используйте SceneManager.GetActiveScene

// This attribute makes this classes messages be executed also in editmode
// (= also of not in playmode)
[ExecuteInEditModo]

// Assure there is a Camera component
[RequireComponent(typeof(Camera))]
public class CameraSetter : MonoBehaviour
{
    [SerializeField] private MainCamera mainCameraAsset;

    // Called on initialize
    // With [ExecuteInEditModo] also called on recompile
    private void Awake ()
    {
        mainCameraAsset.AddPair(SceneManager.GetActiveScene,  GetComponent<Camera>();
    }
}

Чем позже в сцене вы можете использовать список с FirstOrDefault (который не выдает исключение, но возвращает null, если элемент не найден) и Scene.path (потому что имя сцены может быть тем же, и вы не можете сравнить scene непосредственно, поскольку его экземпляр не совпадает с экземпляром, на который есть ссылка), например, например

var camera = mainCameraReference.SceneCameraPairs.FirstOrDefault(pair => pair.scene.path == ScaneManager.GetActiveScene().path);

или словарь типа

 var camera = mainCameraReference.sceneToCamera[ScaneManager.GetActiveScene().path];

Различные типы

Чтобы иметь возможность хранить различные ссылки различных типов (при условии, что только один для каждого типа) вы можете сделать что-то вроде, например,

[CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/Data", order = 1)]
public class References : ScriptableObject
{
    public Camera mainCamera;
    public CharacterController controller;
    public Transform transform;

    // fix for the generic methods
    // a bit dirty maybe but should work
    public void Set(Component component)
    {
        if(component.GetType() == typeof(Camera))
        {
            mainCamera = (Camera) component;
        } 
        else if(component.GetType() == typeof(CharacterController))
        {
            controller = (CharacterController) component;
        }
        else if(component.GetType() == typeof(Transform))
        {
            transform = (Transform) component;
        }
    }

    public void Set(Camera camera)
    {
        mainCamera = camera;
    }

    public void Set(CharacterController characterController )
    {
        controller = characterController ;
    }

    public void Set(Transform characterTransform)
    {
        transform = characterTransform;
    }

    // or simply all at once
    public void Set(Camera camera, CharacterController characterController, Transform characterTransform)
    {
        mainCamera = camera;
        controller = characterController;
        transform = characterTransform;
    }

    // etc
}

Чем вы могли бы иметь один базовый класс-установщик, например,

public abstract class SetterBase<T> : MonoBehaviour where T : Component
{
    // unfortunately you can not serialize generics in 
    // the inspector so for now we stick with only one single ScriptableObject
    public References references;

    privtae void Awake()
    {
        SetReference<T>();
    }

    private void SetReference<T>() where T : Component
    {
        var component = GetComponent<T>();
        references.Set(component);
    }
}

. Теперь вы можете наследовать реализации для каждого типа, который вам нужен / который присутствует в References, например,

public CameraSetter : SetterBase<Camera>
{
    // doesn't have to do anything else ... but could
}
[ 1139] и

public TransformSetter : SetterBase<Transform>
{
    // doesn't have to do anything else ... but could
}

и т. Д.

Или в качестве альтернативы
(и именно поэтому я добавил один сеттер для всего), вы могли бы разрешить его обработку все одним менеджером

public class ReferenceSetter : MonoBehaviour
{
    public References references;

    // Reference those in the inspector as usual
    public Camera camera;
    public Transform transform;
    public CharacterController controller;

    private void Awake()
    {
        references.Set(camera, controller, transform);
    }
}
0
ответ дан derHugo 17 January 2019 в 06:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: