mirror of
https://github.com/oliverbooth/X10D
synced 2024-11-25 15:18:47 +00:00
feat: add Component move/copy
As usual, experimental API - subject to change.
This commit is contained in:
parent
75ac9e2d8f
commit
420ec2433a
@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- X10D: Added `TextWriter.WriteLineNoAlloc(uint[, ReadOnlySpan<char>[, IFormatProvider]])`.
|
- X10D: Added `TextWriter.WriteLineNoAlloc(uint[, ReadOnlySpan<char>[, IFormatProvider]])`.
|
||||||
- X10D: Added `TextWriter.WriteLineNoAlloc(long[, ReadOnlySpan<char>[, IFormatProvider]])`.
|
- X10D: Added `TextWriter.WriteLineNoAlloc(long[, ReadOnlySpan<char>[, IFormatProvider]])`.
|
||||||
- X10D: Added `TextWriter.WriteLineNoAlloc(ulong[, ReadOnlySpan<char>[, IFormatProvider]])`.
|
- X10D: Added `TextWriter.WriteLineNoAlloc(ulong[, ReadOnlySpan<char>[, IFormatProvider]])`.
|
||||||
|
- X10D.Unity: Added `Component.CopyTo(GameObject)` and `Component.MoveTo(GameObject)`.
|
||||||
|
- X10D.Unity: Added `GameObject.CopyComponent<T>(GameObject)` and `GameObject.MoveComponent<T>(GameObject)`.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- X10D: `DateTime.Age(DateTime)` and `DateTimeOffset.Age(DateTimeOffset)` parameter renamed from `asOf` to `referenceDate`.
|
- X10D: `DateTime.Age(DateTime)` and `DateTimeOffset.Age(DateTimeOffset)` parameter renamed from `asOf` to `referenceDate`.
|
||||||
|
@ -1,14 +1,77 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.TestTools;
|
using UnityEngine.TestTools;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace X10D.Unity.Tests
|
namespace X10D.Unity.Tests
|
||||||
{
|
{
|
||||||
public class ComponentTests
|
public class ComponentTests
|
||||||
{
|
{
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator CopyTo_ShouldCopyComponent_GivenComponent()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
var sourceComponent = source.AddComponent<Rigidbody>();
|
||||||
|
sourceComponent.mass = 10.0f;
|
||||||
|
sourceComponent.useGravity = false;
|
||||||
|
|
||||||
|
var target = new GameObject();
|
||||||
|
sourceComponent.CopyTo(target);
|
||||||
|
|
||||||
|
Assert.That(target.TryGetComponent(out Rigidbody targetComponent));
|
||||||
|
Assert.That(targetComponent.mass, Is.EqualTo(10.0f));
|
||||||
|
Assert.That(targetComponent.useGravity, Is.False);
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
Object.Destroy(target);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator CopyTo_ShouldThrowArgumentNullException_GivenNullComponent()
|
||||||
|
{
|
||||||
|
var target = new GameObject();
|
||||||
|
Rigidbody rigidbody = null!;
|
||||||
|
|
||||||
|
Assert.Throws<ArgumentNullException>(() => rigidbody.CopyTo(target));
|
||||||
|
|
||||||
|
Object.Destroy(target);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator CopyTo_ShouldThrowArgumentNullException_GivenNullTarget()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
var rigidbody = source.AddComponent<Rigidbody>();
|
||||||
|
GameObject target = null!;
|
||||||
|
|
||||||
|
Assert.Throws<ArgumentNullException>(() => rigidbody.CopyTo(target));
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator CopyTo_ShouldThrowInvalidOperationException_GivenDuplicate()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
var rigidbody = source.AddComponent<Rigidbody>();
|
||||||
|
|
||||||
|
var target = new GameObject();
|
||||||
|
target.AddComponent<Rigidbody>();
|
||||||
|
|
||||||
|
Assert.Throws<InvalidOperationException>(() => rigidbody.CopyTo(target));
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
Object.Destroy(target);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
[UnityTest]
|
[UnityTest]
|
||||||
public IEnumerator GetComponentsInChildrenOnly_ShouldIgnoreParent()
|
public IEnumerator GetComponentsInChildrenOnly_ShouldIgnoreParent()
|
||||||
{
|
{
|
||||||
@ -16,13 +79,80 @@ namespace X10D.Unity.Tests
|
|||||||
var rigidbody = parent.AddComponent<Rigidbody>();
|
var rigidbody = parent.AddComponent<Rigidbody>();
|
||||||
|
|
||||||
var child = new GameObject();
|
var child = new GameObject();
|
||||||
child.transform.SetParent(parent.transform);
|
|
||||||
child.AddComponent<Rigidbody>();
|
child.AddComponent<Rigidbody>();
|
||||||
|
|
||||||
|
yield return null;
|
||||||
|
|
||||||
Rigidbody[] components = rigidbody.GetComponentsInChildrenOnly<Rigidbody>();
|
Rigidbody[] components = rigidbody.GetComponentsInChildrenOnly<Rigidbody>();
|
||||||
Assert.That(components.Length, Is.EqualTo(1));
|
Assert.That(components.Length, Is.EqualTo(1));
|
||||||
Assert.That(child, Is.EqualTo(components[0].gameObject));
|
Assert.That(child, Is.EqualTo(components[0].gameObject));
|
||||||
|
|
||||||
|
Object.Destroy(parent);
|
||||||
|
Object.Destroy(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator MoveTo_ShouldCopyComponent_GivenComponent()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
var sourceComponent = source.AddComponent<Rigidbody>();
|
||||||
|
sourceComponent.mass = 10f;
|
||||||
|
sourceComponent.useGravity = false;
|
||||||
|
|
||||||
|
var target = new GameObject();
|
||||||
|
sourceComponent.MoveTo(target);
|
||||||
|
|
||||||
|
// effects of Destroy only take place at end of frame
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
Assert.That(sourceComponent == null);
|
||||||
|
Assert.That(source.TryGetComponent(out Rigidbody _), Is.False);
|
||||||
|
Assert.That(target.TryGetComponent(out Rigidbody targetComponent));
|
||||||
|
Assert.That(targetComponent.mass, Is.EqualTo(10.0f));
|
||||||
|
Assert.That(targetComponent.useGravity, Is.False);
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
Object.Destroy(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator MoveTo_ShouldThrowArgumentNullException_GivenNullComponent()
|
||||||
|
{
|
||||||
|
var target = new GameObject();
|
||||||
|
Rigidbody rigidbody = null!;
|
||||||
|
|
||||||
|
Assert.Throws<ArgumentNullException>(() => rigidbody.MoveTo(target));
|
||||||
|
|
||||||
|
Object.Destroy(target);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator MoveTo_ShouldThrowArgumentNullException_GivenNullTarget()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
var rigidbody = source.AddComponent<Rigidbody>();
|
||||||
|
GameObject target = null!;
|
||||||
|
|
||||||
|
Assert.Throws<ArgumentNullException>(() => rigidbody.MoveTo(target));
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator MoveTo_ShouldThrowInvalidOperationException_GivenDuplicate()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
var rigidbody = source.AddComponent<Rigidbody>();
|
||||||
|
|
||||||
|
var target = new GameObject();
|
||||||
|
target.AddComponent<Rigidbody>();
|
||||||
|
|
||||||
|
Assert.Throws<InvalidOperationException>(() => rigidbody.MoveTo(target));
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
Object.Destroy(target);
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,107 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.TestTools;
|
using UnityEngine.TestTools;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace X10D.Unity.Tests
|
namespace X10D.Unity.Tests
|
||||||
{
|
{
|
||||||
public class GameObjectTests
|
public class GameObjectTests
|
||||||
{
|
{
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator CopyComponent_ShouldCopyComponent_GivenComponent()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
var sourceComponent = source.AddComponent<Rigidbody>();
|
||||||
|
sourceComponent.mass = 10.0f;
|
||||||
|
sourceComponent.useGravity = false;
|
||||||
|
|
||||||
|
var target = new GameObject();
|
||||||
|
source.CopyComponent<Rigidbody>(target);
|
||||||
|
|
||||||
|
Assert.That(target.TryGetComponent(out Rigidbody targetComponent));
|
||||||
|
Assert.That(targetComponent.mass, Is.EqualTo(10.0f));
|
||||||
|
Assert.That(targetComponent.useGravity, Is.False);
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
Object.Destroy(target);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator CopyComponent_ShouldThrowArgumentNullException_GivenNullComponentType()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
var target = new GameObject();
|
||||||
|
Type componentType = null!;
|
||||||
|
|
||||||
|
Assert.Throws<ArgumentNullException>(() => source.CopyComponent(componentType, target));
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
Object.Destroy(target);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator CopyComponent_ShouldThrowArgumentNullException_GivenNullGameObject()
|
||||||
|
{
|
||||||
|
var target = new GameObject();
|
||||||
|
GameObject source = null!;
|
||||||
|
|
||||||
|
Assert.Throws<ArgumentNullException>(() => source.CopyComponent<Rigidbody>(target));
|
||||||
|
Assert.Throws<ArgumentNullException>(() => source.CopyComponent(typeof(Rigidbody), target));
|
||||||
|
|
||||||
|
Object.Destroy(target);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator CopyComponent_ShouldThrowArgumentNullException_GivenNullTarget()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
GameObject target = null!;
|
||||||
|
|
||||||
|
Assert.Throws<ArgumentNullException>(() => source.CopyComponent<Rigidbody>(target));
|
||||||
|
Assert.Throws<ArgumentNullException>(() => source.CopyComponent(typeof(Rigidbody), target));
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator CopyComponent_ShouldThrowInvalidOperationException_GivenInvalidComponent()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
var target = new GameObject();
|
||||||
|
|
||||||
|
Assert.Throws<InvalidOperationException>(() => source.CopyComponent<Rigidbody>(target));
|
||||||
|
Assert.Throws<InvalidOperationException>(() => source.CopyComponent(typeof(Rigidbody), target));
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
Object.Destroy(target);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator CopyComponent_ShouldThrowInvalidOperationException_GivenDuplicate()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
source.AddComponent<Rigidbody>();
|
||||||
|
|
||||||
|
var target = new GameObject();
|
||||||
|
target.AddComponent<Rigidbody>();
|
||||||
|
|
||||||
|
Assert.Throws<InvalidOperationException>(() => source.CopyComponent<Rigidbody>(target));
|
||||||
|
Assert.Throws<InvalidOperationException>(() => source.CopyComponent(typeof(Rigidbody), target));
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
Object.Destroy(target);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
[UnityTest]
|
[UnityTest]
|
||||||
public IEnumerator GetComponentsInChildrenOnly_ShouldIgnoreParent()
|
public IEnumerator GetComponentsInChildrenOnly_ShouldIgnoreParent()
|
||||||
{
|
{
|
||||||
@ -23,6 +116,8 @@ namespace X10D.Unity.Tests
|
|||||||
Assert.That(components.Length, Is.EqualTo(1));
|
Assert.That(components.Length, Is.EqualTo(1));
|
||||||
Assert.That(child, Is.EqualTo(components[0].gameObject));
|
Assert.That(child, Is.EqualTo(components[0].gameObject));
|
||||||
|
|
||||||
|
Object.Destroy(parent);
|
||||||
|
Object.Destroy(child);
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,6 +153,103 @@ namespace X10D.Unity.Tests
|
|||||||
first.LookAt(Vector3.right);
|
first.LookAt(Vector3.right);
|
||||||
Assert.That(firstTransform.rotation, Is.EqualTo(expected));
|
Assert.That(firstTransform.rotation, Is.EqualTo(expected));
|
||||||
|
|
||||||
|
Object.Destroy(first);
|
||||||
|
Object.Destroy(second);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator MoveComponent_ShouldCopyComponent_GivenComponent()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
var sourceComponent = source.AddComponent<Rigidbody>();
|
||||||
|
sourceComponent.mass = 10.0f;
|
||||||
|
sourceComponent.useGravity = false;
|
||||||
|
|
||||||
|
var target = new GameObject();
|
||||||
|
source.MoveComponent<Rigidbody>(target);
|
||||||
|
|
||||||
|
// effects of Destroy only take place at end of frame
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
Assert.That(sourceComponent == null);
|
||||||
|
Assert.That(source.TryGetComponent(out Rigidbody _), Is.False);
|
||||||
|
Assert.That(target.TryGetComponent(out Rigidbody targetComponent));
|
||||||
|
Assert.That(targetComponent.mass, Is.EqualTo(10.0f));
|
||||||
|
Assert.That(targetComponent.useGravity, Is.False);
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
Object.Destroy(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator MoveComponent_ShouldThrowArgumentNullException_GivenNullComponentType()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
var target = new GameObject();
|
||||||
|
Type componentType = null!;
|
||||||
|
|
||||||
|
Assert.Throws<ArgumentNullException>(() => source.MoveComponent(componentType, target));
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
Object.Destroy(target);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator MoveComponent_ShouldThrowArgumentNullException_GivenNullGameObject()
|
||||||
|
{
|
||||||
|
var target = new GameObject();
|
||||||
|
GameObject source = null!;
|
||||||
|
|
||||||
|
Assert.Throws<ArgumentNullException>(() => source.MoveComponent<Rigidbody>(target));
|
||||||
|
Assert.Throws<ArgumentNullException>(() => source.MoveComponent(typeof(Rigidbody), target));
|
||||||
|
|
||||||
|
Object.Destroy(target);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator MoveComponent_ShouldThrowArgumentNullException_GivenNullTarget()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
GameObject target = null!;
|
||||||
|
|
||||||
|
Assert.Throws<ArgumentNullException>(() => source.MoveComponent<Rigidbody>(target));
|
||||||
|
Assert.Throws<ArgumentNullException>(() => source.MoveComponent(typeof(Rigidbody), target));
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator MoveComponent_ShouldThrowInvalidOperationException_GivenInvalidComponent()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
var target = new GameObject();
|
||||||
|
|
||||||
|
Assert.Throws<InvalidOperationException>(() => source.MoveComponent<Rigidbody>(target));
|
||||||
|
Assert.Throws<InvalidOperationException>(() => source.MoveComponent(typeof(Rigidbody), target));
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
Object.Destroy(target);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator MoveComponent_ShouldThrowInvalidOperationException_GivenDuplicate()
|
||||||
|
{
|
||||||
|
var source = new GameObject();
|
||||||
|
source.AddComponent<Rigidbody>();
|
||||||
|
|
||||||
|
var target = new GameObject();
|
||||||
|
target.AddComponent<Rigidbody>();
|
||||||
|
|
||||||
|
Assert.Throws<InvalidOperationException>(() => source.MoveComponent<Rigidbody>(target));
|
||||||
|
Assert.Throws<InvalidOperationException>(() => source.MoveComponent(typeof(Rigidbody), target));
|
||||||
|
|
||||||
|
Object.Destroy(source);
|
||||||
|
Object.Destroy(target);
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,6 +274,9 @@ namespace X10D.Unity.Tests
|
|||||||
Assert.That(child.layer, Is.EqualTo(layer));
|
Assert.That(child.layer, Is.EqualTo(layer));
|
||||||
Assert.That(grandChild.layer, Is.EqualTo(layer));
|
Assert.That(grandChild.layer, Is.EqualTo(layer));
|
||||||
|
|
||||||
|
Object.Destroy(parent);
|
||||||
|
Object.Destroy(child);
|
||||||
|
Object.Destroy(grandChild);
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,6 +298,8 @@ namespace X10D.Unity.Tests
|
|||||||
second.SetParent(first);
|
second.SetParent(first);
|
||||||
Assert.That(second.transform.parent, Is.EqualTo(first.transform));
|
Assert.That(second.transform.parent, Is.EqualTo(first.transform));
|
||||||
|
|
||||||
|
Object.Destroy(first);
|
||||||
|
Object.Destroy(second);
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,4 +70,19 @@
|
|||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Update="src\ExceptionMessages.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>ExceptionMessages.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="src\ExceptionMessages.Designer.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>ExceptionMessages.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
using UnityEngine;
|
using System.Globalization;
|
||||||
|
using System.Reflection;
|
||||||
|
using UnityEngine;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace X10D.Unity;
|
namespace X10D.Unity;
|
||||||
|
|
||||||
@ -7,6 +10,95 @@ namespace X10D.Unity;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class ComponentExtensions
|
public static class ComponentExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the component to another game object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="component">The component to copy.</param>
|
||||||
|
/// <param name="target">The game object to which the component will be copied.</param>
|
||||||
|
/// <typeparam name="T">The type of the component to copy.</typeparam>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <para><paramref name="component" /> is <see langword="null" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="target" /> is <see langword="null" />.</para>
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// <paramref name="target" /> already has a component of type <typeparamref name="T" />.
|
||||||
|
/// </exception>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method will destroy the component on the source game object, creating a new instance on the target. Use with
|
||||||
|
/// caution.
|
||||||
|
/// </remarks>
|
||||||
|
public static void CopyTo<T>(this T component, GameObject target)
|
||||||
|
where T : Component
|
||||||
|
{
|
||||||
|
if (component == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(component));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target.TryGetComponent(out T targetComponent))
|
||||||
|
{
|
||||||
|
string message = ExceptionMessages.ComponentAlreadyExists;
|
||||||
|
message = string.Format(CultureInfo.CurrentCulture, message, target.name, typeof(T).Name);
|
||||||
|
throw new InvalidOperationException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
targetComponent = target.AddComponent<T>();
|
||||||
|
|
||||||
|
var typeInfo = typeof(T).GetTypeInfo();
|
||||||
|
CopyFields(typeInfo, component, targetComponent);
|
||||||
|
CopyProperties(typeInfo, component, targetComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the component to another game object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="component">The component to copy.</param>
|
||||||
|
/// <param name="target">The game object to which the component will be copied.</param>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <para><paramref name="component" /> is <see langword="null" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="target" /> is <see langword="null" />.</para>
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// <paramref name="target" /> already has a component of the same type.
|
||||||
|
/// </exception>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method will destroy the component on the source game object, creating a new instance on the target. Use with
|
||||||
|
/// caution.
|
||||||
|
/// </remarks>
|
||||||
|
public static void CopyTo(this Component component, GameObject target)
|
||||||
|
{
|
||||||
|
if (component == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(component));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
var componentType = component.GetType();
|
||||||
|
if (target.TryGetComponent(componentType, out Component targetComponent))
|
||||||
|
{
|
||||||
|
string message = ExceptionMessages.ComponentAlreadyExists;
|
||||||
|
message = string.Format(CultureInfo.CurrentCulture, message, target.name, componentType.Name);
|
||||||
|
throw new InvalidOperationException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
targetComponent = target.AddComponent(componentType);
|
||||||
|
|
||||||
|
var typeInfo = componentType.GetTypeInfo();
|
||||||
|
CopyFields(typeInfo, component, targetComponent);
|
||||||
|
CopyProperties(typeInfo, component, targetComponent);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns an array of components of the specified type, excluding components that live on the object to which this
|
/// Returns an array of components of the specified type, excluding components that live on the object to which this
|
||||||
/// component is attached.
|
/// component is attached.
|
||||||
@ -18,4 +110,124 @@ public static class ComponentExtensions
|
|||||||
{
|
{
|
||||||
return component.gameObject.GetComponentsInChildrenOnly<T>();
|
return component.gameObject.GetComponentsInChildrenOnly<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Moves the component to another game object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="component">The component to move.</param>
|
||||||
|
/// <param name="target">The game object to which the component will be moved.</param>
|
||||||
|
/// <typeparam name="T">The type of the component to move.</typeparam>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <para><paramref name="component" /> is <see langword="null" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="target" /> is <see langword="null" />.</para>
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// <paramref name="target" /> already has a component of type <typeparamref name="T" />.
|
||||||
|
/// </exception>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method will destroy the component on the source game object, creating a new instance on the target. Use with
|
||||||
|
/// caution.
|
||||||
|
/// </remarks>
|
||||||
|
public static void MoveTo<T>(this T component, GameObject target)
|
||||||
|
where T : Component
|
||||||
|
{
|
||||||
|
if (component == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(component));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
component.CopyTo(target);
|
||||||
|
Object.Destroy(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Moves the component to another game object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="component">The component to move.</param>
|
||||||
|
/// <param name="target">The game object to which the component will be moved.</param>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <para><paramref name="component" /> is <see langword="null" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="target" /> is <see langword="null" />.</para>
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// <paramref name="target" /> already has a component of the same type.
|
||||||
|
/// </exception>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method will destroy the component on the source game object, creating a new instance on the target. Use with
|
||||||
|
/// caution.
|
||||||
|
/// </remarks>
|
||||||
|
public static void MoveTo(this Component component, GameObject target)
|
||||||
|
{
|
||||||
|
if (component == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(component));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
component.CopyTo(target);
|
||||||
|
Object.Destroy(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CopyFields<T>(TypeInfo typeInfo, T component, T targetComponent)
|
||||||
|
where T : Component
|
||||||
|
{
|
||||||
|
foreach (FieldInfo field in typeInfo.DeclaredFields)
|
||||||
|
{
|
||||||
|
if (field.IsStatic)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
object fieldValue = GetNewReferences(component, targetComponent, field.GetValue(component));
|
||||||
|
field.SetValue(targetComponent, fieldValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CopyProperties<T>(TypeInfo typeInfo, T component, T targetComponent)
|
||||||
|
where T : Component
|
||||||
|
{
|
||||||
|
foreach (PropertyInfo property in typeInfo.DeclaredProperties)
|
||||||
|
{
|
||||||
|
if (!property.CanRead || !property.CanWrite)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodInfo getMethod = property.GetMethod;
|
||||||
|
MethodInfo setMethod = property.SetMethod;
|
||||||
|
if (getMethod.IsStatic || setMethod.IsStatic)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
object propertyValue = GetNewReferences(component, targetComponent, property.GetValue(component));
|
||||||
|
property.SetValue(targetComponent, propertyValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object GetNewReferences<T>(T component, T targetComponent, object value)
|
||||||
|
where T : Component
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(value, component))
|
||||||
|
{
|
||||||
|
value = targetComponent;
|
||||||
|
}
|
||||||
|
else if (ReferenceEquals(value, component.gameObject))
|
||||||
|
{
|
||||||
|
value = targetComponent.gameObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
80
X10D.Unity/src/ExceptionMessages.Designer.cs
generated
Normal file
80
X10D.Unity/src/ExceptionMessages.Designer.cs
generated
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace X10D.Unity {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
/// </summary>
|
||||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
|
// class via a tool like ResGen or Visual Studio.
|
||||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
|
// with the /str option, or rebuild your VS project.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class ExceptionMessages {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal ExceptionMessages() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("X10D.Unity.src.ExceptionMessages", typeof(ExceptionMessages).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||||
|
/// resource lookups using this strongly typed resource class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to The game object {0} already has a component of type {1}..
|
||||||
|
/// </summary>
|
||||||
|
internal static string ComponentAlreadyExists {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ComponentAlreadyExists", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to The game object {0} does not have a component of type {1}..
|
||||||
|
/// </summary>
|
||||||
|
internal static string ComponentDoesNotExist {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ComponentDoesNotExist", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
X10D.Unity/src/ExceptionMessages.resx
Normal file
34
X10D.Unity/src/ExceptionMessages.resx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<root>
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>1.3</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
|
||||||
|
PublicKeyToken=b77a5c561934e089
|
||||||
|
</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
|
||||||
|
PublicKeyToken=b77a5c561934e089
|
||||||
|
</value>
|
||||||
|
</resheader>
|
||||||
|
|
||||||
|
<data name="ComponentDoesNotExist" xml:space="preserve">
|
||||||
|
<value>The game object {0} does not have a component of type {1}.</value>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<data name="ComponentAlreadyExists" xml:space="preserve">
|
||||||
|
<value>The game object {0} already has a component of type {1}.</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
@ -1,4 +1,6 @@
|
|||||||
|
using System.Globalization;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace X10D.Unity;
|
namespace X10D.Unity;
|
||||||
|
|
||||||
@ -7,6 +9,90 @@ namespace X10D.Unity;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class GameObjectExtensions
|
public static class GameObjectExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the component of the specified type from one game object to another.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="gameObject">The game object from which to copy the component.</param>
|
||||||
|
/// <param name="target">The game object to which the component will be copied.</param>
|
||||||
|
/// <typeparam name="T">The type of the component to copy.</typeparam>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <para><paramref name="gameObject" /> is <see langword="null" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="target" /> is <see langword="null" />.</para>
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// <para><paramref name="gameObject" /> does not have a component of type <typeparamref name="T" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="target" /> already has a component of type <typeparamref name="T" />.</para>
|
||||||
|
/// </exception>
|
||||||
|
public static void CopyComponent<T>(this GameObject gameObject, GameObject target)
|
||||||
|
where T : Component
|
||||||
|
{
|
||||||
|
if (gameObject == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(gameObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gameObject.TryGetComponent(out T sourceComponent))
|
||||||
|
{
|
||||||
|
string message = ExceptionMessages.ComponentDoesNotExist;
|
||||||
|
message = string.Format(CultureInfo.CurrentCulture, message, gameObject.name, typeof(T).Name);
|
||||||
|
throw new InvalidOperationException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceComponent.CopyTo(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the component of the specified type from one game object to another.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="gameObject">The game object from which to copy the component.</param>
|
||||||
|
/// <param name="componentType">The type of the component to copy.</param>
|
||||||
|
/// <param name="target">The game object to which the component will be copied.</param>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <para><paramref name="gameObject" /> is <see langword="null" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="target" /> is <see langword="null" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="target" /> is <see langword="null" />.</para>
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// <para><paramref name="gameObject" /> does not have a component of type <paramref name="componentType" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="target" /> already has a component of type <paramref name="componentType" />.</para>
|
||||||
|
/// </exception>
|
||||||
|
public static void CopyComponent(this GameObject gameObject, Type componentType, GameObject target)
|
||||||
|
{
|
||||||
|
if (gameObject == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(gameObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (componentType is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(componentType));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gameObject.TryGetComponent(componentType, out Component sourceComponent))
|
||||||
|
{
|
||||||
|
string message = ExceptionMessages.ComponentDoesNotExist;
|
||||||
|
message = string.Format(CultureInfo.CurrentCulture, message, gameObject.name, componentType.Name);
|
||||||
|
throw new InvalidOperationException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceComponent.CopyTo(target);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns an array of components of the specified type, excluding components that live on this game object.
|
/// Returns an array of components of the specified type, excluding components that live on this game object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -171,6 +257,100 @@ public static class GameObjectExtensions
|
|||||||
gameObject.transform.LookAt(target, worldUp);
|
gameObject.transform.LookAt(target, worldUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Moves the component of the specified type from one game object to another.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="gameObject">The game object from which to move the component.</param>
|
||||||
|
/// <param name="target">The game object to which the component will be moved.</param>
|
||||||
|
/// <typeparam name="T">The type of the component to copy.</typeparam>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <para><paramref name="gameObject" /> is <see langword="null" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="target" /> is <see langword="null" />.</para>
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// <para><paramref name="gameObject" /> does not have a component of type <typeparamref name="T" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="target" /> already has a component of type <typeparamref name="T" />.</para>
|
||||||
|
/// </exception>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method will destroy the component on the source game object, creating a new instance on the target. Use with
|
||||||
|
/// caution.
|
||||||
|
/// </remarks>
|
||||||
|
public static void MoveComponent<T>(this GameObject gameObject, GameObject target)
|
||||||
|
where T : Component
|
||||||
|
{
|
||||||
|
if (gameObject == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(gameObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gameObject.TryGetComponent(out T sourceComponent))
|
||||||
|
{
|
||||||
|
string message = ExceptionMessages.ComponentDoesNotExist;
|
||||||
|
message = string.Format(CultureInfo.CurrentCulture, message, gameObject.name, typeof(T).Name);
|
||||||
|
throw new InvalidOperationException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceComponent.MoveTo(target);
|
||||||
|
Object.Destroy(sourceComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Moves the component of the specified type from one game object to another.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="gameObject">The game object from which to move the component.</param>
|
||||||
|
/// <param name="componentType">The type of the component to copy.</param>
|
||||||
|
/// <param name="target">The game object to which the component will be moved.</param>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <para><paramref name="gameObject" /> is <see langword="null" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="componentType" /> is <see langword="null" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="target" /> is <see langword="null" />.</para>
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// <para><paramref name="gameObject" /> does not have a component of type <paramref name="componentType" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="target" /> already has a component of type <paramref name="componentType" />.</para>
|
||||||
|
/// </exception>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method will destroy the component on the source game object, creating a new instance on the target. Use with
|
||||||
|
/// caution.
|
||||||
|
/// </remarks>
|
||||||
|
public static void MoveComponent(this GameObject gameObject, Type componentType, GameObject target)
|
||||||
|
{
|
||||||
|
if (gameObject == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(gameObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (componentType is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(componentType));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gameObject.TryGetComponent(componentType, out Component sourceComponent))
|
||||||
|
{
|
||||||
|
string message = ExceptionMessages.ComponentDoesNotExist;
|
||||||
|
message = string.Format(CultureInfo.CurrentCulture, message, gameObject.name, componentType.Name);
|
||||||
|
throw new InvalidOperationException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceComponent.MoveTo(target);
|
||||||
|
Object.Destroy(sourceComponent);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the new layer of this game object and its children, recursively.
|
/// Sets the new layer of this game object and its children, recursively.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Loading…
Reference in New Issue
Block a user