first commit

This commit is contained in:
lethanhsonvsp 2025-11-17 15:36:52 +07:00
commit 6f2eafa33c
14093 changed files with 1253472 additions and 0 deletions

6
.vsconfig Normal file
View File

@ -0,0 +1,6 @@
{
"version": "1.0",
"components": [
"Microsoft.VisualStudio.Workload.ManagedGame"
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1182
Assembly-CSharp.csproj Normal file

File diff suppressed because it is too large Load Diff

8
Assets/Editor.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b8f01b30fae5b13418a2569db8043cd4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,83 @@
using UnityEngine;
using UnityEditor;
using UnityEngine.Splines;
using System.Linq;
[CustomEditor(typeof(MultiSplineFollower))]
public class MultiSplineFollowerEditor : Editor
{
public override void OnInspectorGUI()
{
// Vẽ inspector mặc định (hiện các trường routes, routes1, routes2, speed, rotationSpeed, ...)
base.OnInspectorGUI();
MultiSplineFollower follower = (MultiSplineFollower)target;
// Hiển thị từng nhóm route
DrawRouteGroup(follower.routes, "Routes (Nhóm 0)");
DrawRouteGroup(follower.routes1, "Routes1 (Nhóm 1)");
DrawRouteGroup(follower.routes2, "Routes2 (Nhóm 2)");
if (GUI.changed)
{
EditorUtility.SetDirty(follower);
}
}
private void DrawRouteGroup(SplineRoute[] routeArray, string groupLabel)
{
if (routeArray == null) return;
EditorGUILayout.Space();
EditorGUILayout.LabelField(groupLabel, EditorStyles.boldLabel);
for (int r = 0; r < routeArray.Length; r++)
{
var route = routeArray[r];
if (route == null) continue;
EditorGUILayout.BeginVertical("box");
EditorGUILayout.LabelField($"Route {r + 1}", EditorStyles.miniBoldLabel);
// START
if (route.splineStart != null)
{
int knotCount = route.splineStart.Spline?.Knots.Count() ?? 0;
if (knotCount > 0)
{
string[] options = Enumerable.Range(0, knotCount).Select(i => $"Knot {i}").ToArray();
route.startKnotIndex = EditorGUILayout.Popup("Start Knot", route.startKnotIndex, options);
}
else
{
EditorGUILayout.HelpBox("SplineStart không có knot nào.", MessageType.Warning);
}
}
else
{
EditorGUILayout.HelpBox("Chưa gán splineStart", MessageType.Info);
}
// END
if (route.splineEnd != null)
{
int knotCount = route.splineEnd.Spline?.Knots.Count() ?? 0;
if (knotCount > 0)
{
string[] options = Enumerable.Range(0, knotCount).Select(i => $"Knot {i}").ToArray();
route.endKnotIndex = EditorGUILayout.Popup("End Knot", route.endKnotIndex, options);
}
else
{
EditorGUILayout.HelpBox("SplineEnd không có knot nào.", MessageType.Warning);
}
}
else
{
EditorGUILayout.HelpBox("Chưa gán splineEnd", MessageType.Info);
}
EditorGUILayout.EndVertical();
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1ffddca8b3c7373478b7fe510bc6dbf6

8
Assets/MTvsRB.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 56af2f4d77b09fb40a86e6dada50633d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,109 @@
fileFormatVersion: 2
guid: caf08c3793403bc48ba74cbf5e737aef
ModelImporter:
serializedVersion: 22200
internalIDToNameTable: []
externalObjects: {}
materials:
materialImportMode: 2
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
removeConstantScaleCurves: 0
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 0
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importPhysicalCameras: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
nodeNameCollisionStrategy: 1
fileIdsGeneration: 2
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
bakeAxisConversion: 0
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
optimizeBones: 1
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVMarginMethod: 1
secondaryUVMinLightmapResolution: 40
secondaryUVMinObjectScale: 1
secondaryUVPackMargin: 4
useFileScale: 1
strictVertexDataChecks: 0
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
autoGenerateAvatarMappingIfUnspecified: 1
animationType: 2
humanoidOversampling: 1
avatarSetup: 0
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
importBlendShapeDeformPercent: 1
remapMaterialsIfMaterialImportModeIsNone: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,109 @@
fileFormatVersion: 2
guid: 17b5baefb35c2f748afeaaeeb9dae1fe
ModelImporter:
serializedVersion: 22200
internalIDToNameTable: []
externalObjects: {}
materials:
materialImportMode: 2
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
removeConstantScaleCurves: 0
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 0
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importPhysicalCameras: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
nodeNameCollisionStrategy: 1
fileIdsGeneration: 2
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
bakeAxisConversion: 0
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
optimizeBones: 1
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVMarginMethod: 1
secondaryUVMinLightmapResolution: 40
secondaryUVMinObjectScale: 1
secondaryUVPackMargin: 4
useFileScale: 1
strictVertexDataChecks: 0
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
autoGenerateAvatarMappingIfUnspecified: 1
animationType: 2
humanoidOversampling: 1
avatarSetup: 0
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
importBlendShapeDeformPercent: 1
remapMaterialsIfMaterialImportModeIsNone: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/MTvsRB/nn.fbx Normal file

Binary file not shown.

109
Assets/MTvsRB/nn.fbx.meta Normal file
View File

@ -0,0 +1,109 @@
fileFormatVersion: 2
guid: 4df3875c0537a7c42bc2bb770b0fcc07
ModelImporter:
serializedVersion: 22200
internalIDToNameTable: []
externalObjects: {}
materials:
materialImportMode: 2
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
removeConstantScaleCurves: 0
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 0
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importPhysicalCameras: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
nodeNameCollisionStrategy: 1
fileIdsGeneration: 2
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
bakeAxisConversion: 0
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
optimizeBones: 1
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVMarginMethod: 1
secondaryUVMinLightmapResolution: 40
secondaryUVMinObjectScale: 1
secondaryUVPackMargin: 4
useFileScale: 1
strictVertexDataChecks: 0
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
autoGenerateAvatarMappingIfUnspecified: 1
animationType: 2
humanoidOversampling: 1
avatarSetup: 0
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
importBlendShapeDeformPercent: 1
remapMaterialsIfMaterialImportModeIsNone: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

8
Assets/Material.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a34a84e8d70220a4a8ba8a06e4780976
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

83
Assets/Material/B.mat Normal file
View File

@ -0,0 +1,83 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: B
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 0.121885024, g: 0.22150913, b: 0.7830189, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 38ba582044bb218469509f4a19eb8dd1
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

83
Assets/Material/G.mat Normal file
View File

@ -0,0 +1,83 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: G
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 0.022694906, g: 0.9622642, b: 0.055024367, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 035505eab6c86fe4bb2d04eb353c15fe
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,83 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Ground
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 79e1fb9ab2984984fa2b24d48d12b058
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

83
Assets/Material/Sl.mat Normal file
View File

@ -0,0 +1,83 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Sl
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5796b43c03668174b93fdf9f95d6d997
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

83
Assets/Material/Y.mat Normal file
View File

@ -0,0 +1,83 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Y
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 0.9811321, g: 0.8973006, b: 0.14346743, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c69b86e0102069e429231bacccc1d799
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

8
Assets/Plugins.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 105277358663b34429b2eff35224ce2a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 86e5c3715256cd2418e8d81f9e03e2e5
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Plugins/MQTTnet.dll Normal file

Binary file not shown.

View File

@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: be41d36aacf33014c9c8e4822b0fbec0
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

8
Assets/Scenes.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a0f2f3c558cdb97498814583547437e6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aea883fa2a6d7914b869e4de0b9b1487
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9fc0d4010bbf28b4594072e72b8655ab
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7aed28d9922a38a4b8d81c54b5078d1b
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 23800000
userData:
assetBundleName:
assetBundleVariant:

8
Assets/Script.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cb86729fa0fa7484682ccf5db8a0d3f4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,266 @@
using UnityEngine;
using UnityEngine.Splines;
using Unity.Mathematics;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
public class MultiSplineFollower : MonoBehaviour
{
[Header("Tuyến đường 1")]
public SplineRoute[] routes;
[Header("Tuyến đường 2")]
public SplineRoute[] routes1;
[Header("Tuyến đường 3")]
public SplineRoute[] routes2;
[Header("Cài đặt chuyển động")]
public float speed = 2f;
public float rotationSpeed = 180f;
public float angleThreshold = 30f;
[Header("Cài đặt quét TCIA")]
public float scanRadius = 0.5f; // bán kính quét đối tượng TCIA quanh follower
private int currentRouteIndex = 0;
private int currentRouteGroup = 0; // 0 = routes, 1 = routes1, 2 = routes2
private float t = 0f;
private bool onFirstSpline = true;
private bool isDelaying = false;
void Start()
{
if (GetActiveRoutes() == null || GetActiveRoutes().Length == 0) return;
var activeRoutes = GetActiveRoutes();
InitRoute(activeRoutes[0]);
t = activeRoutes[0].tStart;
transform.position = activeRoutes[0].splineStart.EvaluatePosition(0, t);
}
void Update()
{
var activeRoutes = GetActiveRoutes();
if (activeRoutes == null || activeRoutes.Length == 0) return;
if (currentRouteIndex >= activeRoutes.Length) return;
if (isDelaying) return;
SplineRoute route = activeRoutes[currentRouteIndex];
if (onFirstSpline)
MoveOnSpline(route.splineStart, ref t, route.tCommonA, true, route);
else
MoveOnSpline(route.splineEnd, ref t, route.tEnd, false, route);
}
SplineRoute[] GetActiveRoutes()
{
switch (currentRouteGroup)
{
case 0: return routes;
case 1: return routes1;
case 2: return routes2;
default: return null;
}
}
void InitRoute(SplineRoute route)
{
BezierKnot knotStart = route.splineStart.Spline.Knots.ElementAt(route.startKnotIndex);
BezierKnot knotEnd = route.splineEnd.Spline.Knots.ElementAt(route.endKnotIndex);
Vector3 knotX = route.splineStart.transform.TransformPoint((Vector3)knotStart.Position);
Vector3 knotY = route.splineEnd.transform.TransformPoint((Vector3)knotEnd.Position);
route.commonPoint = FindCommonPoint(route.splineStart, route.splineEnd);
float3 nearest;
SplineUtility.GetNearestPoint(route.splineStart.Spline,
(float3)route.splineStart.transform.InverseTransformPoint(knotX),
out nearest, out route.tStart);
SplineUtility.GetNearestPoint(route.splineStart.Spline,
(float3)route.splineStart.transform.InverseTransformPoint(route.commonPoint),
out nearest, out route.tCommonA);
SplineUtility.GetNearestPoint(route.splineEnd.Spline,
(float3)route.splineEnd.transform.InverseTransformPoint(route.commonPoint),
out nearest, out route.tCommonB);
SplineUtility.GetNearestPoint(route.splineEnd.Spline,
(float3)route.splineEnd.transform.InverseTransformPoint(knotY),
out nearest, out route.tEnd);
onFirstSpline = true;
}
void MoveOnSpline(SplineContainer spline, ref float t, float targetT, bool first, SplineRoute route)
{
Vector3 pos = spline.EvaluatePosition(0, t);
Vector3 tangent = Vector3.Normalize((Vector3)spline.EvaluateTangent(0, t));
if (route.reverseDirection) tangent = -tangent;
float angle = Vector3.Angle(transform.forward, tangent);
if (angle > angleThreshold)
{
Quaternion targetRot = Quaternion.LookRotation(tangent, Vector3.up);
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRot, rotationSpeed * Time.deltaTime);
return;
}
float dir = (targetT > t) ? 1f : -1f;
t += dir * (Time.deltaTime * speed / spline.CalculateLength(0));
if ((dir > 0 && t >= targetT) || (dir < 0 && t <= targetT))
t = targetT;
pos = spline.EvaluatePosition(0, t);
tangent = Vector3.Normalize((Vector3)spline.EvaluateTangent(0, t));
if (route.reverseDirection) tangent = -tangent;
transform.position = pos;
transform.rotation = Quaternion.LookRotation(tangent, Vector3.up);
if (first && Mathf.Approximately(t, targetT))
{
onFirstSpline = false;
t = route.tCommonB;
}
else if (!first && Mathf.Approximately(t, targetT))
{
if (route.delayAtEnd)
{
StartCoroutine(DelayAndNextRoute(route));
}
else
{
NextRoute();
}
}
}
IEnumerator DelayAndNextRoute(SplineRoute route)
{
isDelaying = true;
if (route.attachTCIAObjects)
{
Debug.Log($"[{route.splineStart.name}] attachTCIAObjects = TRUE → quét và gắn TCIA");
AttachTCIAChildren();
}
else
{
DetachTCIAChildren();
}
yield return new WaitForSeconds(2f);
isDelaying = false;
NextRoute();
}
void AttachTCIAChildren()
{
GameObject[] allObjects = Object.FindObjectsByType<GameObject>(FindObjectsSortMode.None);
foreach (GameObject obj in allObjects)
{
if (!obj.activeInHierarchy || obj == this.gameObject)
continue;
if (obj.name.ToUpper().Contains("TCIA"))
{
float distance = Vector3.Distance(transform.position, obj.transform.position);
if (distance <= scanRadius)
{
obj.transform.SetParent(this.transform, true);
}
}
}
}
void DetachTCIAChildren()
{
List<Transform> childrenToDetach = new List<Transform>();
foreach (Transform child in transform)
{
if (child.name.ToUpper().Contains("TCIA"))
{
childrenToDetach.Add(child);
}
}
foreach (Transform child in childrenToDetach)
{
child.SetParent(null, true);
}
}
void NextRoute()
{
var activeRoutes = GetActiveRoutes();
currentRouteIndex++;
if (activeRoutes != null && currentRouteIndex < activeRoutes.Length)
{
InitRoute(activeRoutes[currentRouteIndex]);
t = activeRoutes[currentRouteIndex].tStart;
transform.position = activeRoutes[currentRouteIndex].splineStart.EvaluatePosition(0, t);
}
else
{
// Hết nhóm hiện tại → chuyển sang nhóm tiếp theo
currentRouteGroup++;
currentRouteIndex = 0;
var nextGroupRoutes = GetActiveRoutes();
if (nextGroupRoutes != null && nextGroupRoutes.Length > 0)
{
Debug.Log($"Chuyển sang nhóm tuyến: {currentRouteGroup}");
InitRoute(nextGroupRoutes[0]);
t = nextGroupRoutes[0].tStart;
transform.position = nextGroupRoutes[0].splineStart.EvaluatePosition(0, t);
}
else
{
Debug.Log("Hoàn thành toàn bộ tuyến đường!");
}
}
}
Vector3 FindCommonPoint(SplineContainer s1, SplineContainer s2)
{
foreach (var knotA in s1.Spline.Knots)
{
Vector3 pA = s1.transform.TransformPoint((Vector3)knotA.Position);
foreach (var knotB in s2.Spline.Knots)
{
Vector3 pB = s2.transform.TransformPoint((Vector3)knotB.Position);
if (Vector3.Distance(pA, pB) < 0.01f)
return pA;
}
}
Debug.LogWarning("Không tìm thấy điểm chung!");
return Vector3.zero;
}
}
[System.Serializable]
public class SplineRoute
{
public SplineContainer splineStart;
public int startKnotIndex;
public SplineContainer splineEnd;
public int endKnotIndex;
public bool reverseDirection;
public bool delayAtEnd;
public bool attachTCIAObjects = true; // true = gắn TCIA, false = tách TCIA khi delay
[HideInInspector] public Vector3 commonPoint;
[HideInInspector] public float tStart;
[HideInInspector] public float tCommonA;
[HideInInspector] public float tCommonB;
[HideInInspector] public float tEnd;
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d70a28c0bc38f874b90921a56348fa45

8
Assets/Script/mqtt.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e7dfee9ec7d58794ab85f959fe69a880
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,46 @@
using UnityEngine;
using MQTTnet;
using MQTTnet.Client;
using System.Threading.Tasks;
using System.Text;
public class MqttClientController : MonoBehaviour
{
public string mqttBrokerAddress = "broker.hivemq.com";
public int mqttPort = 1883;
public IMqttClient mqttClient { get; private set; }
public bool IsConnected => mqttClient?.IsConnected ?? false;
async void Start()
{
var factory = new MqttFactory();
mqttClient = factory.CreateMqttClient();
var options = new MqttClientOptionsBuilder()
.WithClientId("UnityClient")
.WithTcpServer(mqttBrokerAddress, mqttPort)
.WithCleanSession()
.Build();
mqttClient.ConnectedAsync += async e =>
{
Debug.Log("Connected to MQTT Broker.");
await Task.CompletedTask;
};
mqttClient.DisconnectedAsync += async e =>
{
Debug.Log("Disconnected from MQTT Broker.");
await Task.CompletedTask;
};
try
{
await mqttClient.ConnectAsync(options);
}
catch (System.Exception ex)
{
Debug.LogError($"MQTT connection failed: {ex.Message}");
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b4a12d2d54e4c53428426127da4b9c51
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,30 @@
using MQTTnet;
using MQTTnet.Protocol;
using UnityEngine;
public class MqttOJ : MonoBehaviour
{
public MqttClientController mqttClientController;
public string topic = "unity/position";
void Update()
{
if (mqttClientController != null && mqttClientController.IsConnected)
{
Vector3 position = transform.position;
string message = JsonUtility.ToJson(position);
var mqttMessage = new MqttApplicationMessageBuilder()
.WithTopic(topic)
.WithPayload(message)
.WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce)
.Build();
mqttClientController.mqttClient.PublishAsync(mqttMessage);
}
else
{
//Debug.LogWarning("MQTT client is not connected. Skipping publish.");
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3925dfe133e555c4d8cd03541df378b5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,54 @@
using MQTTnet;
using MQTTnet.Client;
using System;
using System.Threading.Tasks;
using UnityEngine;
public class MqttUnityClient : MonoBehaviour
{
private IMqttClient _mqttClient;
private async void Start()
{
await ConnectAsync();
// Đăng ký chủ đề để nhận tin nhắn
await _mqttClient.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic("unity/topic").Build());
}
private async Task ConnectAsync()
{
var factory = new MqttFactory();
_mqttClient = factory.CreateMqttClient();
var options = new MqttClientOptionsBuilder()
.WithClientId("UnityClient")
.WithTcpServer("broker.hivemq.com", 1883)
.WithCleanSession()
.Build();
_mqttClient.ApplicationMessageReceivedAsync += e =>
{
// Xử lý tin nhắn nhận được
var message = System.Text.Encoding.UTF8.GetString(e.ApplicationMessage.PayloadSegment);
Debug.Log($"Received: {message}");
return Task.CompletedTask;
};
await _mqttClient.ConnectAsync(options);
}
public async Task PublishAsync(string topic, string payload)
{
var message = new MqttApplicationMessageBuilder()
.WithTopic(topic)
.WithPayload(payload)
.WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce)
.Build();
if (_mqttClient.IsConnected)
{
await _mqttClient.PublishAsync(message);
Debug.Log($"Published: {payload} to {topic}");
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6c7b03c5c34c4e840b9fcf3204cdb029
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

BIN
Library/AnnotationManager Normal file

Binary file not shown.

BIN
Library/ArtifactDB Normal file

Binary file not shown.

BIN
Library/ArtifactDB-lock Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More