Я только что написал 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 ')
}
Вы не можете не напрямую прикреплять ссылки на сцены к 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);
}
}