Делайте больше Ñ JobSystem
(Russian translation from English by Maxim Voloshin)
Мое введение в Job System приводит большой ÑпиÑок функций Unity, доÑтупных Ð´Ð»Ñ C# задач, но Ñтот ÑпиÑок неполный. Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ Ñ Ñ…Ð¾Ñ‡Ñƒ дополнить его недавно добавленными в 2018.2 функциÑми, а также некоторыми мощными функциÑми верÑии 2018.1, которые мы пропуÑтили в прошлой Ñтатье. Многие из них не опиÑаны в замечаниÑÑ… к релизу Unity. Читайте, чтобы узнать больше о том, что вы можете Ñделать Ñ ÑиÑтемой задач C#!
ПотокобезопаÑные функции
Как упоминаетÑÑ Ð² введении в Job System, многие функции Unity помечены или атрибутом [ThreadSafe]
или [FreeFunction]
и IsThreadSafe
возвращает true
. Ðиже приведен обновленный ÑпиÑок таких функций. Строки, помеченные Ñимволом *
в Ñамом начале, были добавлены в Unity 2018.2:
*AnimationCurve: private extern int AddKey_Internal_Injected(ref Keyframe key); *AnimationCurve: private extern Keyframe[] GetKeys(); *AnimationCurve: private extern void SetKeys(Keyframe[] keys); *AnimationCurve: private int AddKey_Internal(Keyframe key) *AnimationCurve: private Keyframe GetKey(int index) *AnimationCurve: private static extern IntPtr Internal_Create(Keyframe[] keys); *AnimationCurve: private static extern void Internal_Destroy(IntPtr ptr); *AnimationCurve: public extern float Evaluate(float time); *AnimationCurve: public extern int AddKey(float time, float value); *AnimationCurve: public extern void RemoveKey(int index); *AnimationCurve: public extern void SmoothTangents(int index, float weight); *AnimationCurve: public int MoveKey(int index, Keyframe key) *AnimationCurve: public extern int length { get; } *AnimationCurve: public extern WrapMode postWrapMode { set; } *AnimationCurve: public extern WrapMode preWrapMode { set; } *AnimationHumanStream: private float GetFootHeight(bool left) *AnimationHumanStream: private float GetHumanScale() *AnimationHumanStream: private float InternalGetGoalWeightPosition(AvatarIKGoal index) *AnimationHumanStream: private float InternalGetGoalWeightRotation(AvatarIKGoal index) *AnimationHumanStream: private float InternalGetHintWeightPosition(AvatarIKHint index) *AnimationHumanStream: private float InternalGetMuscle(MuscleHandle muscle) *AnimationHumanStream: private Quaternion InternalGetBodyLocalRotation() *AnimationHumanStream: private Quaternion InternalGetBodyRotation() *AnimationHumanStream: private Quaternion InternalGetGoalLocalRotation(AvatarIKGoal index) *AnimationHumanStream: private Quaternion InternalGetGoalRotation(AvatarIKGoal index) *AnimationHumanStream: private Quaternion InternalGetGoalRotationFromPose(AvatarIKGoal index) *AnimationHumanStream: private Vector3 GetLeftFootVelocity() *AnimationHumanStream: private Vector3 GetRightFootVelocity() *AnimationHumanStream: private Vector3 InternalGetBodyLocalPosition() *AnimationHumanStream: private Vector3 InternalGetBodyPosition() *AnimationHumanStream: private Vector3 InternalGetGoalLocalPosition(AvatarIKGoal index) *AnimationHumanStream: private Vector3 InternalGetGoalPosition(AvatarIKGoal index) *AnimationHumanStream: private Vector3 InternalGetGoalPositionFromPose(AvatarIKGoal index) *AnimationHumanStream: private Vector3 InternalGetHintPosition(AvatarIKHint index) *AnimationHumanStream: private void InternalResetToStancePose() *AnimationHumanStream: private void InternalSetBodyLocalPosition(Vector3 value) *AnimationHumanStream: private void InternalSetBodyLocalRotation(Quaternion value) *AnimationHumanStream: private void InternalSetBodyPosition(Vector3 value) *AnimationHumanStream: private void InternalSetBodyRotation(Quaternion value) *AnimationHumanStream: private void InternalSetGoalLocalPosition(AvatarIKGoal index, Vector3 pos) *AnimationHumanStream: private void InternalSetGoalLocalRotation(AvatarIKGoal index, Quaternion rot) *AnimationHumanStream: private void InternalSetGoalPosition(AvatarIKGoal index, Vector3 pos) *AnimationHumanStream: private void InternalSetGoalRotation(AvatarIKGoal index, Quaternion rot) *AnimationHumanStream: private void InternalSetGoalWeightPosition(AvatarIKGoal index, float value) *AnimationHumanStream: private void InternalSetGoalWeightRotation(AvatarIKGoal index, float value) *AnimationHumanStream: private void InternalSetHintPosition(AvatarIKHint index, Vector3 pos) *AnimationHumanStream: private void InternalSetHintWeightPosition(AvatarIKHint index, float value) *AnimationHumanStream: private void InternalSetLookAtBodyWeight(float weight) *AnimationHumanStream: private void InternalSetLookAtClampWeight(float weight) *AnimationHumanStream: private void InternalSetLookAtEyesWeight(float weight) *AnimationHumanStream: private void InternalSetLookAtHeadWeight(float weight) *AnimationHumanStream: private void InternalSetLookAtPosition(Vector3 lookAtPosition) *AnimationHumanStream: private void InternalSetMuscle(MuscleHandle muscle, float value) *AnimationHumanStream: private void InternalSolveIK() *AnimationStream: private AnimationHumanStream GetHumanStream() *AnimationStream: private AnimationStream InternalGetInputStream(int index) *AnimationStream: private bool GetIsHumanStream() *AnimationStream: private float GetDeltaTime() *AnimationStream: private int GetInputStreamCount() *AnimationStream: private Quaternion GetRootMotionRotation() *AnimationStream: private Vector3 GetAngularVelocity() *AnimationStream: private Vector3 GetRootMotionPosition() *AnimationStream: private Vector3 GetVelocity() *AnimationStream: private void InternalReadSceneTransforms() *AnimationStream: private void InternalWriteSceneTransforms() *AnimationStream: private void SetAngularVelocity(Vector3 velocity) *AnimationStream: private void SetVelocity(Vector3 velocity) Animator: public static extern int StringToHash(string name); AnimatorControllerPlayable: private static extern int StringToHash(string name); *Application: public static extern RuntimePlatform platform { get; } *AsyncOperation: private static extern void InternalDestroy(IntPtr ptr); *AtomicSafetyHandle: internal static void CheckReadAndThrowNoEarlyOut(AtomicSafetyHandle handle) *AtomicSafetyHandle: internal static void CheckWriteAndThrowNoEarlyOut(AtomicSafetyHandle handle) AtomicSafetyHandle: public static AtomicSafetyHandle Create() AtomicSafetyHandle: public static AtomicSafetyHandle GetTempUnsafePtrSliceHandle() *AtomicSafetyHandle: public static bool GetAllowReadOrWriteAccess(AtomicSafetyHandle handle) AtomicSafetyHandle: public static EnforceJobResult EnforceAllBufferJobsHaveCompleted(AtomicSafetyHandle handle) AtomicSafetyHandle: public static EnforceJobResult EnforceAllBufferJobsHaveCompletedAndDisableReadWrite(AtomicSafetyHandle handle) AtomicSafetyHandle: public static EnforceJobResult EnforceAllBufferJobsHaveCompletedAndRelease(AtomicSafetyHandle handle) *AtomicSafetyHandle: public static extern void PrepareUndisposable(ref AtomicSafetyHandle handle); AtomicSafetyHandle: public static extern void UseSecondaryVersion(ref AtomicSafetyHandle handle); AtomicSafetyHandle: public static int GetReaderArray(AtomicSafetyHandle handle, int maxCount, IntPtr output) *AtomicSafetyHandle: public static JobHandle GetWriter(AtomicSafetyHandle handle) AtomicSafetyHandle: public static string GetReaderName(AtomicSafetyHandle handle, int readerIndex) AtomicSafetyHandle: public static string GetWriterName(AtomicSafetyHandle handle) *AtomicSafetyHandle: public static void CheckDeallocateAndThrow(AtomicSafetyHandle handle) *AtomicSafetyHandle: public static void CheckGetSecondaryDataPointerAndThrow(AtomicSafetyHandle handle) *AtomicSafetyHandle: public static void CheckWriteAndBumpSecondaryVersion(AtomicSafetyHandle handle) AtomicSafetyHandle: public static void Release(AtomicSafetyHandle handle) AtomicSafetyHandle: public static void SetAllowReadOrWriteAccess(AtomicSafetyHandle handle, bool allowReadWriteAccess) AtomicSafetyHandle: public static void SetAllowSecondaryVersionWriting(AtomicSafetyHandle handle, bool allowWriting) AudioSampleProvider: private static extern bool InternalGetEnableSampleFramesAvailableEvents(uint providerId); AudioSampleProvider: private static extern bool InternalGetEnableSilencePadding(uint id); AudioSampleProvider: private static extern bool InternalIsValid(uint providerId); *AudioSampleProvider: private static extern IntPtr InternalGetConsumeSampleFramesNativeFunctionPtr(); AudioSampleProvider: private static extern uint InternalGetAvailableSampleFrameCount(uint providerId); AudioSampleProvider: private static extern uint InternalGetFreeSampleFrameCount(uint providerId); AudioSampleProvider: private static extern uint InternalGetFreeSampleFrameCountLowThreshold(uint providerId); AudioSampleProvider: private static extern uint InternalGetMaxSampleFrameCount(uint providerId); AudioSampleProvider: private static extern void InternalSetEnableSampleFramesAvailableEvents(uint providerId, bool enable); AudioSampleProvider: private static extern void InternalSetEnableSilencePadding(uint id, bool enabled); AudioSampleProvider: private static extern void InternalSetFreeSampleFrameCountLowThreshold(uint providerId, uint sampleFrameCount); AudioSampleProvider: private static extern void InternalSetScriptingPtr(uint providerId, AudioSampleProvider provider); Bounds: private static bool IntersectRayAABB(Ray ray, Bounds bounds, out float dist) Bounds: public bool Contains(Vector3 point) Bounds: public float SqrDistance(Vector3 point) *Bounds: public Vector3 ClosestPoint(Vector3 point) CertificateHandler: private extern void Release(); *CullingGroup: private extern void FinalizerFailure(); CustomEventData: internal static extern void Internal_Destroy(IntPtr ptr); *Device: private static extern void SettvOSNoBackupFlag(string path); *Device: private static extern void tvOSResetNoBackupFlag(string path); Device: public static extern bool RequestStoreReview(); Device: public static extern void ResetNoBackupFlag(string path); Device: public static extern void SetNoBackupFlag(string path); *DictationRecognizer: private static extern void DestroyThreaded(IntPtr self); DownloadHandler: private extern void Release(); *Event: internal extern void CopyFromPtr(IntPtr ptr); *Event: private static extern IntPtr Internal_Copy(IntPtr otherPtr); *Event: private static extern IntPtr Internal_Create(int displayIndex); *Event: private static extern void Internal_Destroy(IntPtr ptr); GcLeaderboard: private static extern void GcLeaderboard_Dispose(IntPtr leaderboard); *Gradient: private extern void Cleanup(); *Gradient: private static extern IntPtr Init(); *Gradient: public Color Evaluate(float time) *Gradient: public extern GradientMode mode { get; set; } *Gradient: public extern void SetKeys(GradientColorKey[] colorKeys, GradientAlphaKey[] alphaKeys); *Gradient: public extern GradientAlphaKey[] alphaKeys { get; set; } *Gradient: public extern GradientColorKey[] colorKeys { get; set; } *GUIStyle: private extern IntPtr GetStyleStatePtr(int idx); *GUIStyle: private static extern IntPtr Internal_Copy(GUIStyle self, GUIStyle other); *GUIStyle: private static extern IntPtr Internal_Create(GUIStyle self); *GUIStyle: private static extern void Internal_Destroy(IntPtr self); *GUIStyleState: private extern void Cleanup(); *GUIStyleState: private static extern IntPtr Init(); JobsUtility: public static extern bool GetWorkStealingRange(ref JobRanges ranges, int jobIndex, out int beginIndex, out int endIndex); JobsUtility: public static extern unsafe void PatchBufferMinMaxRanges(IntPtr bufferRangePatchData, void* jobdata, int startIndex, int rangeSize); *JsonUtility: private static extern object FromJsonInternal(string json, object objectToOverwrite, System.Type type); *JsonUtility: private static extern string ToJsonInternal(object obj, bool prettyPrint); MaterialPropertyBlock: private static extern void DestroyImpl(IntPtr mpb); Mathf: public static Color CorrelatedColorTemperatureToRGB(float kelvin) Mathf: public static extern bool IsPowerOfTwo(int value); Mathf: public static extern float GammaToLinearSpace(float value); Mathf: public static extern float HalfToFloat(ushort val); Mathf: public static extern float LinearToGammaSpace(float value); Mathf: public static extern float PerlinNoise(float x, float y); Mathf: public static extern int ClosestPowerOfTwo(int value); Mathf: public static extern int NextPowerOfTwo(int value); Mathf: public static extern ushort FloatToHalf(float val); *Matrix4x4: private bool IsIdentity() *Matrix4x4: private float GetDeterminant() Matrix4x4: private FrustumPlanes DecomposeProjection() Matrix4x4: private Quaternion GetRotation() Matrix4x4: private Vector3 GetLossyScale() Matrix4x4: public bool ValidTRS() Matrix4x4: public static Matrix4x4 Frustum(float left, float right, float bottom, float top, float zNear, float zFar) Matrix4x4: public static Matrix4x4 Inverse(Matrix4x4 m) Matrix4x4: public static Matrix4x4 LookAt(Vector3 from, Vector3 to, Vector3 up) Matrix4x4: public static Matrix4x4 Ortho(float left, float right, float bottom, float top, float zNear, float zFar) Matrix4x4: public static Matrix4x4 Perspective(float fov, float aspect, float zNear, float zFar) Matrix4x4: public static Matrix4x4 Transpose(Matrix4x4 m) *Matrix4x4: public static Matrix4x4 TRS(Vector3 pos, Quaternion q, Vector3 s) MeshReconstructionServer: internal static extern void DestroyThreaded(IntPtr server); MonoBehaviour: private static extern void ConstructorCheck(Object self); *Native: private static extern void YGConfigFreeInternal(IntPtr config); *Native: private static extern void YGNodeFreeInternal(IntPtr ygNode); NavMeshQuery: private static bool GetPortalPoints(IntPtr navMeshQuery, PolygonId polygon, PolygonId neighbourPolygon, out Vector3 left, out Vector3 right) NavMeshQuery: private static bool IsPositionInPolygon(IntPtr navMeshQuery, Vector3 position, PolygonId polygon) NavMeshQuery: private static bool IsValidPolygon(IntPtr navMeshQuery, PolygonId polygon) *NavMeshQuery: private static extern bool HasNodePool(IntPtr navMeshQuery); NavMeshQuery: private static extern PathQueryStatus EndFindPath(IntPtr navMeshQuery, out int pathSize); NavMeshQuery: private static extern PathQueryStatus UpdateFindPath(IntPtr navMeshQuery, int iterations, out int iterationsPerformed); NavMeshQuery: private static extern unsafe int GetPathResult(IntPtr navMeshQuery, void* path, int maxPath); NavMeshQuery: private static extern unsafe void MoveLocations(IntPtr navMeshQuery, void* locations, void* targets, void* areaMasks, int count); NavMeshQuery: private static extern unsafe void MoveLocationsInSameAreas(IntPtr navMeshQuery, void* locations, void* targets, int count, int areaMask); *NavMeshQuery: private static int GetAgentTypeIdForPolygon(IntPtr navMeshQuery, PolygonId polygon) *NavMeshQuery: private static Matrix4x4 PolygonLocalToWorldMatrix(IntPtr navMeshQuery, PolygonId polygon) *NavMeshQuery: private static Matrix4x4 PolygonWorldToLocalMatrix(IntPtr navMeshQuery, PolygonId polygon) *NavMeshQuery: private static NavMeshLocation MapLocation(IntPtr navMeshQuery, Vector3 position, Vector3 extents, int agentTypeID, int areaMask = -1) *NavMeshQuery: private static NavMeshLocation MoveLocation(IntPtr navMeshQuery, NavMeshLocation location, Vector3 target, int areaMask) *NavMeshQuery: private static NavMeshPolyTypes GetPolygonType(IntPtr navMeshQuery, PolygonId polygon) *NavMeshQuery: private static PathQueryStatus GetClosestPointOnPoly(IntPtr navMeshQuery, PolygonId polygon, Vector3 position, out Vector3 nearest) *NavMeshQuery: private static unsafe PathQueryStatus BeginFindPath(IntPtr navMeshQuery, NavMeshLocation start, NavMeshLocation end, int areaMask, void* costs) NotificationHelper: internal static extern void DestroyLocal(IntPtr target); NotificationHelper: internal static extern void DestroyRemote(IntPtr target); Object: internal static extern bool DoesObjectWithInstanceIDExist(int instanceID); Object: private static extern bool CurrentThreadIsMainThread(); Object: private static extern int GetOffsetOfInstanceIDInCPlusPlusObject(); ObjectGUIState: private static extern void Internal_Destroy(IntPtr ptr); OnDemandResourcesRequest: private static extern void DestroyFromScript(IntPtr ptr); *PhraseRecognizer: private static extern void DestroyThreaded(IntPtr recognizer); Ping: private static extern void Internal_Destroy(IntPtr ptr); *PropertySceneHandle: private bool GetBoolInternal(ref AnimationStream stream) *PropertySceneHandle: private bool HasValidTransform(ref AnimationStream stream) *PropertySceneHandle: private bool IsBound(ref AnimationStream stream) *PropertySceneHandle: private float GetFloatInternal(ref AnimationStream stream) *PropertySceneHandle: private int GetIntInternal(ref AnimationStream stream) *PropertySceneHandle: private void ResolveInternal(ref AnimationStream stream) *PropertySceneHandle: private void SetBoolInternal(ref AnimationStream stream, bool value) *PropertySceneHandle: private void SetFloatInternal(ref AnimationStream stream, float value) *PropertySceneHandle: private void SetIntInternal(ref AnimationStream stream, int value) *PropertyStreamHandle: private bool GetBoolInternal(ref AnimationStream stream) *PropertyStreamHandle: private float GetFloatInternal(ref AnimationStream stream) *PropertyStreamHandle: private int GetIntInternal(ref AnimationStream stream) *PropertyStreamHandle: private void ResolveInternal(ref AnimationStream stream) *PropertyStreamHandle: private void SetBoolInternal(ref AnimationStream stream, bool value) *PropertyStreamHandle: private void SetFloatInternal(ref AnimationStream stream, float value) *PropertyStreamHandle: private void SetIntInternal(ref AnimationStream stream, int value) Quaternion: private static Quaternion Internal_FromEulerRad(Vector3 euler) Quaternion: private static Vector3 Internal_ToEulerRad(Quaternion rotation) Quaternion: private static void Internal_ToAxisAngleRad(Quaternion q, out Vector3 axis, out float angle) Quaternion: public static Quaternion AngleAxis(float angle, Vector3 axis) Quaternion: public static Quaternion FromToRotation(Vector3 fromDirection, Vector3 toDirection) Quaternion: public static Quaternion Inverse(Quaternion rotation) Quaternion: public static Quaternion Lerp(Quaternion a, Quaternion b, float t) Quaternion: public static Quaternion LerpUnclamped(Quaternion a, Quaternion b, float t) Quaternion: public static Quaternion LookRotation(Vector3 forward, Vector3 upwards) Quaternion: public static Quaternion Slerp(Quaternion a, Quaternion b, float t) Quaternion: public static Quaternion SlerpUnclamped(Quaternion a, Quaternion b, float t) RemoteConfigSettings: internal static extern void Internal_Destroy(IntPtr ptr); *Screen: public static extern float dpi { get; } Screen: public static extern int height { get; } Screen: public static extern int width { get; } ScriptableObject: private static extern void CreateScriptableObject(ScriptableObject self); *Shader: public static extern int PropertyToID(string name); *StylePainter: private static extern IntPtr Internal_Create(); *StylePainter: private static extern void Internal_Destroy(IntPtr self); *TerrainData: private static extern int GetBoundaryValue(TerrainData.BoundaryValueType type); *TextGenerator: private static extern IntPtr Internal_Create(); *TextGenerator: private static extern void Internal_Destroy(IntPtr ptr); *TouchScreenKeyboard: private static extern void Internal_Destroy(IntPtr ptr); TransformAccess: private static extern void GetLocalPosition(ref TransformAccess access, out Vector3 p); TransformAccess: private static extern void GetLocalRotation(ref TransformAccess access, out Quaternion r); TransformAccess: private static extern void GetLocalScale(ref TransformAccess access, out Vector3 r); TransformAccess: private static extern void GetPosition(ref TransformAccess access, out Vector3 p); TransformAccess: private static extern void GetRotation(ref TransformAccess access, out Quaternion r); TransformAccess: private static extern void SetLocalPosition(ref TransformAccess access, ref Vector3 p); TransformAccess: private static extern void SetLocalRotation(ref TransformAccess access, ref Quaternion r); TransformAccess: private static extern void SetLocalScale(ref TransformAccess access, ref Vector3 r); TransformAccess: private static extern void SetPosition(ref TransformAccess access, ref Vector3 p); TransformAccess: private static extern void SetRotation(ref TransformAccess access, ref Quaternion r); TransformAccessArray: internal static extern IntPtr GetSortedToUserIndex(IntPtr transformArrayIntPtr); TransformAccessArray: internal static extern IntPtr GetSortedTransformAccess(IntPtr transformArrayIntPtr); *TransformSceneHandle: private bool HasValidTransform(ref AnimationStream stream) *TransformSceneHandle: private Quaternion GetLocalRotationInternal(ref AnimationStream stream) *TransformSceneHandle: private Quaternion GetRotationInternal(ref AnimationStream stream) *TransformSceneHandle: private Vector3 GetLocalPositionInternal(ref AnimationStream stream) *TransformSceneHandle: private Vector3 GetLocalScaleInternal(ref AnimationStream stream) *TransformSceneHandle: private Vector3 GetPositionInternal(ref AnimationStream stream) *TransformSceneHandle: private void SetLocalPositionInternal(ref AnimationStream stream, Vector3 position) *TransformSceneHandle: private void SetLocalRotationInternal(ref AnimationStream stream, Quaternion rotation) *TransformSceneHandle: private void SetLocalScaleInternal(ref AnimationStream stream, Vector3 scale) *TransformSceneHandle: private void SetPositionInternal(ref AnimationStream stream, Vector3 position) *TransformSceneHandle: private void SetRotationInternal(ref AnimationStream stream, Quaternion rotation) *TransformStreamHandle: private Quaternion GetLocalRotationInternal(ref AnimationStream stream) *TransformStreamHandle: private Quaternion GetRotationInternal(ref AnimationStream stream) *TransformStreamHandle: private Vector3 GetLocalPositionInternal(ref AnimationStream stream) *TransformStreamHandle: private Vector3 GetLocalScaleInternal(ref AnimationStream stream) *TransformStreamHandle: private Vector3 GetPositionInternal(ref AnimationStream stream) *TransformStreamHandle: private void ResolveInternal(ref AnimationStream stream) *TransformStreamHandle: private void SetLocalPositionInternal(ref AnimationStream stream, Vector3 position) *TransformStreamHandle: private void SetLocalRotationInternal(ref AnimationStream stream, Quaternion rotation) *TransformStreamHandle: private void SetLocalScaleInternal(ref AnimationStream stream, Vector3 scale) *TransformStreamHandle: private void SetPositionInternal(ref AnimationStream stream, Vector3 position) *TransformStreamHandle: private void SetRotationInternal(ref AnimationStream stream, Quaternion rotation) UnityAnalytHandler: internal static extern void Internal_Destroy(IntPtr ptr); UnityLogWriter: private static extern void WriteStringToUnityLogImpl(string s); UnityWebRequest: private extern void Release(); UnityWebRequest: private static extern string GetWebErrorString(UnityWebRequest.UnityWebRequestError err); UnityWebRequest: public extern void Abort(); UnsafeUtility: internal static extern void LogError(string msg, string filename, int linenumber); UnsafeUtility: private static extern int GetFieldOffsetInClass(FieldInfo field); UnsafeUtility: private static extern int GetFieldOffsetInStruct(FieldInfo field); UnsafeUtility: public static extern bool IsBlittable(Type type); UnsafeUtility: public static extern int SizeOf(Type type); *UnsafeUtility: public static extern unsafe int MemCmp(void* ptr1, void* ptr2, long size); UnsafeUtility: public static extern unsafe void CopyObjectAddressToPtr(object target, void* dstPtr); UnsafeUtility: public static extern unsafe void Free(void* memory, Allocator allocator); UnsafeUtility: public static extern unsafe void MemClear(void* destination, long size); UnsafeUtility: public static extern unsafe void MemCpy(void* destination, void* source, long size); UnsafeUtility: public static extern unsafe void MemCpyReplicate(void* destination, void* source, int size, int count); UnsafeUtility: public static extern unsafe void MemCpyStride(void* destination, int destinationStride, void* source, int sourceStride, int elementSize, int count); UnsafeUtility: public static extern unsafe void MemMove(void* destination, void* source, long size); UnsafeUtility: public static extern unsafe void* Malloc(long size, int alignment, Allocator allocator); UnsafeUtility: public static extern unsafe void* PinGCObjectAndGetAddress(object target, out ulong gcHandle); UnsafeUtility: public static extern void ReleaseGCObject(ulong gcHandle); UploadHandler: private extern void Release(); Vector3: private static extern void OrthoNormalize2(ref Vector3 a, ref Vector3 b); Vector3: private static extern void OrthoNormalize3(ref Vector3 a, ref Vector3 b, ref Vector3 c); Vector3: public static Vector3 RotateTowards(Vector3 current, Vector3 target, float maxRadiansDelta, float maxMagnitudeDelta) Vector3: public static Vector3 Slerp(Vector3 a, Vector3 b, float t) Vector3: public static Vector3 SlerpUnclamped(Vector3 a, Vector3 b, float t)
МножеÑтво разнообразных функций теперь доÑтупно из ÑиÑтемы задач в 2018.2. ПолезноÑÑ‚ÑŒ многих из них ограничена, либо в Ñилу Ñвоей природы, либо в Ñилу того факта, что они принимают ÑÑылочные типы, такие как клаÑÑÑ‹ или маÑÑивы, которые запрещено иÑпользовать в задачах. Ð¥Ð¾Ñ‚Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ из них довольно удобны. Вот некоторые оÑновные моменты:
Bounds.ClosestPoint
: полезна Ð´Ð»Ñ Ñ€ÐµÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ð¸ логики 3D геометрии Ñ‚.к.Physics
не доÑтупенJsonUtility.FromJsonInternal
иToJsonInternal
: JSON ÑÐµÑ€Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¸ деÑÐµÑ€Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐ¿ÐµÑ€ÑŒ может работать вне главного потокаMatrix4x4.IsIdentity
иGetDeterminant
: полезные функции Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð°Ð¼Ð¸UnsafeUtility.MemCmp
: Ðффективное Ñравнение двух блоков памÑти
Ðнимации в C# ÑиÑтеме задач
БольшинÑтво функций выше были добавлены Ð´Ð»Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¸ фичи Animation C# Jobs, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñет задачам манипулировать анимациÑми и транÑформациÑми. Ðто Ñправедливо Ð´Ð»Ñ AnimationHumanStream
, AnimationStream
, PropertySceneHandle
, и Ñпорно Ð´Ð»Ñ TransformSceneHandle
и TransformStreamHandle
. Ðто более Ð³Ð»ÑƒÐ±Ð¾ÐºÐ°Ñ Ñ‚ÐµÐ¼Ð°, выходÑÑ‰Ð°Ñ Ð·Ð° рамки данной Ñтатьи, поÑмотрите примеры Unity Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾ чтобы узнать как Ñто можно иÑпользовать и почерпнуть пару идей что Ñ Ñтим можно Ñделать.
NavMeshQuery
Ð”Ñ€ÑƒÐ³Ð°Ñ Ð±Ð¾Ð»ÑŒÑˆÐ°Ñ Ñ‡Ð°ÑÑ‚ÑŒ вышеприведенных функций – Ñто подкапотные Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ â€œÑкÑпериментальной†Ñтруктуры NavMeshQuery
. СовмеÑтно Ñо ÑвÑзанными Ñ Ð½ÐµÐ¹ Ñтруктурами NavMeshWorld
, PolygonId
, и NavMeshLocation
, она позволÑет опрашивать nav mesh и выполнÑÑ‚ÑŒ поиÑк пути из ÑиÑтемы задач. Ðти операции могут очень интенÑивно иÑпользовать CPU и было бы прекраÑно перенеÑти их из главного потока в задачи. Ð¢Ð°ÐºÐ°Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ÑŒ была “ÑкÑпериментальной†в 2018.1 и продолжает быть таковой в 2018.2. Ð”Ð¾Ñ€Ð¾Ð¶Ð½Ð°Ñ ÐºÐ°Ñ€Ñ‚Ð° Unity на данный момент молчит о том, когда ждать Ñтабильный релиз Ñтого функционала.
RaycastCommand
ОтÑутÑтвует в ÑпиÑке выше и не упомÑнута в замечаниÑÑ… к релизу 2018.1 RaycastCommand
. Ðе ÑÐ¼Ð¾Ñ‚Ñ€Ñ Ð½Ð° то, что она была добавлена в 2018.1 и позволÑла нам Ñоздавать задачи, броÑающие набор лучей и выводить результат в NativeArray
. Пока Physics, в общем Ñлучае, не доÑтупен вне главного потока, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ ÑиÑтему задач, как минимум броÑание лучей поддерживаетÑÑ, как одна из наиболее раÑпроÑтраненных операций Ñ Ñ„Ð¸Ð·Ð¸ÐºÐ¾Ð¹, широко иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÐ¼Ð°Ñ Ð²Ñем, от выÑтрелов до логики передвижениÑ. Ð’ конце концов, Unity хотÑÑ‚ добавить больше команд Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ñ„Ð¸Ð·Ð¸ÐºÐ¾Ð¹, а также поддержку 2D физики.
Заключение
Ð’Ñе больше и больше функционала ÑтановитÑÑ Ð´Ð¾Ñтупно Ð´Ð»Ñ ÑиÑтемы задач C# Ñ ÐºÐ°Ð¶Ð´Ñ‹Ð¼ релизом Unity. Поддержка броÑÐ°Ð½Ð¸Ñ Ð»ÑƒÑ‡ÐµÐ¹ в 2018.1, анимации и JSON в 2018.2 позволÑет нам перенеÑти Ñамые трудоемкие чаÑти из главного потока, что было невозможно в предыдущих верÑиÑÑ… Unity. Ð¡Ñ‚Ð°Ð±Ð¸Ð»ÑŒÐ½Ð°Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ° nav mesh и дополнительные функции Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ñ„Ð¸Ð·Ð¸ÐºÐ¾Ð¹ уже на горизонте, как и ECS. Как только они будут выпущены, еще больше кода может быть конвертировано из Ñтарого API в новый, ориентированный на задачи подход. Ð”ÐµÐ»Ð°Ñ Ñто, мы получаем огромное повышение производительноÑти и Ñнижение ÑнергопотреблениÑ. Дайте мне знать в комментариÑÑ… что Ð’Ñ‹ думаете о такой Ñмене парадигм.