I have improved the existing 'OrificeAligner' plugin.
Since I don't have much knowledge about coding, I asked ChatGPT to assist me with the work.
I specifically requested that it rewrite the code in a different way, excluding the basic logic that is not subject to copyright.
But to be honest, I can't really say that I have a solid understanding of code.
As far as I can tell, most of the structure and wording have been changed, but this is just a beginner’s observation.
Could you please review it and determine whether there are any remaining copyright issues regarding the code?
Additionally, if there are no copyright problems, I would like to know whether it would be permissible to publish a similar plugin.
The original 'OrificeAligner' plugin is licensed under CC BY-NC-SA, so I’m not sure if I would be allowed to release mine under a CC BY license.
Since I don't have much knowledge about coding, I asked ChatGPT to assist me with the work.
I specifically requested that it rewrite the code in a different way, excluding the basic logic that is not subject to copyright.
But to be honest, I can't really say that I have a solid understanding of code.
As far as I can tell, most of the structure and wording have been changed, but this is just a beginner’s observation.
Could you please review it and determine whether there are any remaining copyright issues regarding the code?
Additionally, if there are no copyright problems, I would like to know whether it would be permissible to publish a similar plugin.
The original 'OrificeAligner' plugin is licensed under CC BY-NC-SA, so I’m not sure if I would be allowed to release mine under a CC BY license.
C#:
using UnityEngine;
using SimpleJSON;
using System.Collections.Generic;
using System.Linq;
namespace AutoAlign
{
public class AutoAlignController : MVRScript
{
private Atom targetAtom;
private FreeControllerV3 thisControl;
private JSONStorableStringChooser atomChooser;
private JSONStorableStringChooser bodyPartChooser;
private JSONStorableStringChooser alignModeChooser;
private JSONStorableBool alignPositionJSON;
private JSONStorableBool alignRotationJSON;
private JSONStorableFloat posOffsetXJSON;
private JSONStorableFloat posOffsetYJSON;
private JSONStorableFloat posOffsetZJSON;
private JSONStorableFloat rotOffsetXJSON;
private JSONStorableFloat rotOffsetYJSON;
private JSONStorableFloat rotOffsetZJSON;
private JSONStorableBool oscillatePosXJSON;
private JSONStorableBool oscillatePosYJSON;
private JSONStorableBool oscillatePosZJSON;
private JSONStorableBool oscillateRotXJSON;
private JSONStorableBool oscillateRotYJSON;
private JSONStorableBool oscillateRotZJSON;
private JSONStorableFloat oscillationSpeedJSON;
private JSONStorableFloat oscillationAmplitudeJSON;
private Rigidbody targetRigidbody;
private float oscillationTime;
private readonly List<string> bodyParts = new List<string> { "Mouth", "Vagina", "Anus" };
private readonly List<string> alignModes = new List<string> { "Sync Rotation", "Look At" };
public override void Init()
{
if (containingAtom == null)
{
SuperController.LogError("AutoAlignController: Must be attached to an atom.");
return;
}
thisControl = containingAtom.freeControllers.FirstOrDefault(fc => fc.name == "control");
if (thisControl == null)
{
SuperController.LogError("AutoAlignController: No control found.");
return;
}
atomChooser = new JSONStorableStringChooser("Target Atom", SuperController.singleton.GetAtomUIDsWithRigidbodies(), "", "Target Atom", SyncTargetAtom);
RegisterStringChooser(atomChooser);
CreateFilterablePopup(atomChooser, false);
bodyPartChooser = new JSONStorableStringChooser("Body Part", bodyParts, "Mouth", "Body Part", SyncBodyPart);
RegisterStringChooser(bodyPartChooser);
CreateFilterablePopup(bodyPartChooser, false);
alignModeChooser = new JSONStorableStringChooser("Align Mode", alignModes, "Sync Rotation", "Align Mode");
RegisterStringChooser(alignModeChooser);
CreateFilterablePopup(alignModeChooser, false);
alignPositionJSON = new JSONStorableBool("Align Position", true);
RegisterBool(alignPositionJSON);
CreateToggle(alignPositionJSON);
alignRotationJSON = new JSONStorableBool("Align Rotation", true);
RegisterBool(alignRotationJSON);
CreateToggle(alignRotationJSON);
oscillatePosXJSON = CreateToggleWithLabel("Oscillate Position X", false);
oscillatePosYJSON = CreateToggleWithLabel("Oscillate Position Y", false);
oscillatePosZJSON = CreateToggleWithLabel("Oscillate Position Z", false);
oscillateRotXJSON = CreateToggleWithLabel("Oscillate Rotation X", false);
oscillateRotYJSON = CreateToggleWithLabel("Oscillate Rotation Y", false);
oscillateRotZJSON = CreateToggleWithLabel("Oscillate Rotation Z", false);
oscillationSpeedJSON = new JSONStorableFloat("Oscillation Speed", 1f, 0.1f, 25f);
RegisterFloat(oscillationSpeedJSON);
CreateSlider(oscillationSpeedJSON);
oscillationAmplitudeJSON = new JSONStorableFloat("Oscillation Amplitude", 0.1f, 0.01f, 1f);
RegisterFloat(oscillationAmplitudeJSON);
CreateSlider(oscillationAmplitudeJSON);
posOffsetXJSON = CreateOffsetSlider("Position Offset X", -1f, 1f);
posOffsetYJSON = CreateOffsetSlider("Position Offset Y", -1f, 1f);
posOffsetZJSON = CreateOffsetSlider("Position Offset Z", -1f, 1f);
rotOffsetXJSON = CreateOffsetSlider("Rotation Offset X", -180f, 180f);
rotOffsetYJSON = CreateOffsetSlider("Rotation Offset Y", -180f, 180f);
rotOffsetZJSON = CreateOffsetSlider("Rotation Offset Z", -180f, 180f);
}
private JSONStorableFloat CreateOffsetSlider(string name, float min, float max)
{
var slider = new JSONStorableFloat(name, 0f, min, max);
RegisterFloat(slider);
CreateSlider(slider);
return slider;
}
private JSONStorableBool CreateToggleWithLabel(string label, bool defaultValue)
{
var toggle = new JSONStorableBool(label, defaultValue);
RegisterBool(toggle);
CreateToggle(toggle);
return toggle;
}
private void SyncTargetAtom(string uid)
{
targetAtom = SuperController.singleton.GetAtomByUid(uid);
SyncBodyPart(bodyPartChooser.val);
}
private void SyncBodyPart(string part)
{
if (targetAtom == null) return;
string triggerName = "MouthTrigger";
if (part == "Mouth")
{
triggerName = "MouthTrigger";
}
else if (part == "Vagina")
{
triggerName = "VaginaTrigger";
}
else if (part == "Anus")
{
triggerName = "LabiaTrigger";
}
targetRigidbody = targetAtom.rigidbodies.FirstOrDefault(rb => rb.name == triggerName);
if (targetRigidbody == null)
{
SuperController.LogError("AutoAlignController: Target Rigidbody not found.");
}
}
void FixedUpdate()
{
if (targetRigidbody == null || thisControl == null) return;
oscillationTime += Time.deltaTime * oscillationSpeedJSON.val;
float oscValue = Mathf.Sin(oscillationTime) * oscillationAmplitudeJSON.val;
Vector3 targetPos = targetRigidbody.transform.position;
Vector3 targetUp = targetRigidbody.transform.up;
if (alignPositionJSON.val)
{
Vector3 posOffset = new Vector3(posOffsetXJSON.val, posOffsetYJSON.val, posOffsetZJSON.val);
Vector3 oscOffset = Vector3.zero;
if (oscillatePosXJSON.val) oscOffset.x = oscValue;
if (oscillatePosYJSON.val) oscOffset.y = oscValue;
if (oscillatePosZJSON.val) oscOffset.z = oscValue;
thisControl.transform.position = targetPos + thisControl.transform.rotation * (posOffset + oscOffset);
}
if (alignRotationJSON.val)
{
Quaternion rotation;
if (alignModeChooser.val == "Sync Rotation")
{
rotation = targetRigidbody.transform.rotation;
}
else
{
rotation = Quaternion.LookRotation(targetUp, Vector3.up);
}
Vector3 eulerOffset = new Vector3(rotOffsetXJSON.val, rotOffsetYJSON.val, rotOffsetZJSON.val);
if (oscillateRotXJSON.val) eulerOffset.x += oscValue * 10f;
if (oscillateRotYJSON.val) eulerOffset.y += oscValue * 10f;
if (oscillateRotZJSON.val) eulerOffset.z += oscValue * 10f;
thisControl.transform.rotation = rotation * Quaternion.Euler(eulerOffset);
}
}
}
}