Initial commit: Unity WordConnect project

This commit is contained in:
2025-08-01 19:12:05 +08:00
commit f14db75802
3503 changed files with 448337 additions and 0 deletions

View File

@ -0,0 +1,18 @@
// // ©2015 - 2025 Candy Smith
// // All rights reserved
// // Redistribution of this software is strictly not allowed.
// // Copy of this software can be obtained from unity asset store only.
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// // THE SOFTWARE.
namespace WordsToolkit.Scripts.GUI.Tutorials
{
public class TutorialExtraWords : TutorialPopupUI
{
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e7d3fb59d92c40efa3b8e25774fd7ed2
timeCreated: 1748240603

View File

@ -0,0 +1,66 @@
// // ©2015 - 2025 Candy Smith
// // All rights reserved
// // Redistribution of this software is strictly not allowed.
// // Copy of this software can be obtained from unity asset store only.
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// // THE SOFTWARE.
using UnityEngine;
using WordsToolkit.Scripts.Localization;
using WordsToolkit.Scripts.Popups;
using WordsToolkit.Scripts.Settings;
namespace WordsToolkit.Scripts.GUI.Tutorials
{
public class TutorialPopupBase : Popup
{
[SerializeField]
private LocalizedTextMeshProUGUI text;
protected TutorialSettingsData tutorialData;
protected GameObject[] GetObjectsOfTagsToShow()
{
if (tagsToShow == null || tagsToShow.Length == 0)
return null;
var tags = new GameObject[tagsToShow.Length];
for (int i = 0; i < tagsToShow.Length; i++)
{
var t = GameObject.FindGameObjectWithTag(tagsToShow[i]);
if (t == null)
Debug.LogError($"TutorialPopupBase: GetTagsToShow: {tagsToShow[i]} found: {t != null}");
if (t != null)
{
tags[i] = t;
}
}
return tags;
}
public void SetTitle(string getText)
{
if (text != null)
{
text.text = getText;
}
}
public void SetData(TutorialSettingsData tutorialData)
{
this.tutorialData = tutorialData;
ShowTags(tutorialData.tagsToShow);
}
public TutorialSettingsData GetData()
{
return tutorialData;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 62879301cce14e229585844c2d2e1d5e
timeCreated: 1748157756

View File

@ -0,0 +1,45 @@
// // ©2015 - 2025 Candy Smith
// // All rights reserved
// // Redistribution of this software is strictly not allowed.
// // Copy of this software can be obtained from unity asset store only.
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// // THE SOFTWARE.
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
using VContainer;
using WordsToolkit.Scripts.Enums;
using WordsToolkit.Scripts.Gameplay;
using WordsToolkit.Scripts.Gameplay.Managers;
using WordsToolkit.Scripts.System;
namespace WordsToolkit.Scripts.GUI.Tutorials
{
public class TutorialPopupGame : TutorialWordSubstitution
{
public override void AfterShowAnimation()
{
base.AfterShowAnimation();
var words = levelManager.GetCurrentLevel().GetWords(gameManager.language);
ReplaceWordForTutorial(words[0]);
SelectWordAnimation(words[0]);
var tiles = fieldManager.GetTilesWord(words[0]);
if (tiles != null && tiles.Count > 0)
{
foreach (var tile in tiles)
{
if (tile != null)
{
MakeObjectVisible(tile.gameObject);
}
}
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 71d0ca3b60b74d44bcff8d7f94a91ac8
timeCreated: 1748156902

View File

@ -0,0 +1,95 @@
// // ©2015 - 2025 Candy Smith
// // All rights reserved
// // Redistribution of this software is strictly not allowed.
// // Copy of this software can be obtained from unity asset store only.
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// // THE SOFTWARE.
using UnityEngine;
using System.Collections;
namespace WordsToolkit.Scripts.GUI.Tutorials
{
public class TutorialPopupUI : TutorialPopupBase
{
[SerializeField]
protected GameObject arrow;
protected Coroutine arrowAnimation;
protected GameObject targetObject;
protected float arrowOffset = 1.0f;
public override void AfterShowAnimation()
{
base.AfterShowAnimation();
targetObject = GetObjectsOfTagsToShow()[0];
if (targetObject != null && arrow != null)
{
Vector3 targetPos = targetObject.transform.position;
if (targetPos.x < 0)
{
arrow.transform.localScale = new Vector3(-1, 1, 1);
arrowOffset = 1.0f;
}
else
{
arrow.transform.localScale = new Vector3(1, 1, 1);
arrowOffset = -1.0f;
}
UpdateArrowPosition();
arrow.SetActive(true);
arrowAnimation = StartCoroutine(AnimateArrow());
}
}
protected void UpdateArrowPosition()
{
if (targetObject != null && arrow != null)
{
Vector3 targetPos = targetObject.transform.position;
arrow.transform.position = new Vector3(targetPos.x + arrowOffset, targetPos.y, targetPos.z);
}
}
protected IEnumerator AnimateArrow()
{
float time = 0f;
float wobbleAmount = 0.1f;
while (true)
{
time += Time.deltaTime * 2f; // Complete one cycle in 0.5 seconds
UpdateArrowPosition();
// Add small wobble animation
float wobble = Mathf.PingPong(time, 1f) * wobbleAmount;
Vector3 currentPos = arrow.transform.position;
arrow.transform.position = new Vector3(currentPos.x + (arrowOffset > 0 ? wobble : -wobble), currentPos.y, currentPos.z);
yield return null;
}
}
public override void AfterHideAnimation()
{
base.AfterHideAnimation();
if (arrow != null)
{
arrow.SetActive(false);
if (arrowAnimation != null)
{
StopCoroutine(arrowAnimation);
arrowAnimation = null;
}
}
targetObject = null;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2fb722bb3ee846c9b50fb4fdd88276d1
timeCreated: 1748086797

View File

@ -0,0 +1,36 @@
// // ©2015 - 2025 Candy Smith
// // All rights reserved
// // Redistribution of this software is strictly not allowed.
// // Copy of this software can be obtained from unity asset store only.
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// // THE SOFTWARE.
namespace WordsToolkit.Scripts.GUI.Tutorials
{
public class TutorialRedGem : TutorialWordSubstitution
{
public override void AfterShowAnimation()
{
base.AfterShowAnimation();
var tiles = fieldManager.GetTilesWordWithSpecialItems(out var word);
ReplaceWordForTutorial(word);
SelectWordAnimation(word);
// make tiles above UI
if (tiles != null && tiles.Count > 0)
{
foreach (var tile in tiles)
{
if (tile != null)
{
MakeObjectVisible(tile.gameObject);
}
}
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c69baf91b6764c6d9e5a061a9ca87959
timeCreated: 1748266655

View File

@ -0,0 +1,32 @@
// // ©2015 - 2025 Candy Smith
// // All rights reserved
// // Redistribution of this software is strictly not allowed.
// // Copy of this software can be obtained from unity asset store only.
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// // THE SOFTWARE.
using UnityEngine;
namespace WordsToolkit.Scripts.GUI.Tutorials
{
public class TutorialTime : TutorialPopupUI
{
public override void AfterShowAnimation()
{
base.AfterShowAnimation();
targetObject = GetObjectsOfTagsToShow()[0];
if (targetObject != null && arrow != null)
{
UpdateArrowPosition();
arrow.SetActive(true);
arrowAnimation = StartCoroutine(AnimateArrow());
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 08a2702beacc4f3eae33f19c8558a0c1
timeCreated: 1750149586

View File

@ -0,0 +1,88 @@
// // ©2015 - 2025 Candy Smith
// // All rights reserved
// // Redistribution of this software is strictly not allowed.
// // Copy of this software can be obtained from unity asset store only.
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// // THE SOFTWARE.
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
using VContainer;
using WordsToolkit.Scripts.Enums;
using WordsToolkit.Scripts.Gameplay;
using WordsToolkit.Scripts.Gameplay.Managers;
using WordsToolkit.Scripts.System;
namespace WordsToolkit.Scripts.GUI.Tutorials
{
public class TutorialWordSubstitution : TutorialPopupBase
{
[Inject]
protected LevelManager levelManager;
[Inject]
protected GameManager gameManager;
[SerializeField]
private GameObject hand;
protected void ReplaceWordForTutorial(string word)
{
localizationManager.SetPairPlaceholder("word", word.ToUpper());
SetTitle(localizationManager.GetText(tutorialData.kind.ToString(), "Tutorial"));
}
protected void SelectWordAnimation(string wordForTutorial)
{
var selection = FindObjectOfType<WordSelectionManager>();
var letters = selection.GetLetters(wordForTutorial);
AnimateHandToLetters(letters);
EventManager.GetEvent<string>(EGameEvent.WordOpened).Subscribe(OnWordOpened);
}
private void OnWordOpened(string obj)
{
EventManager.GetEvent<string>(EGameEvent.WordOpened).Unsubscribe(OnWordOpened);
Close();
}
private void OnDestroy()
{
if (hand != null)
{
hand.SetActive(false);
hand.transform.DOKill();
}
}
private void AnimateHandToLetters(List<LetterButton> letters)
{
var path = new List<Vector3>();
foreach (var letter in letters)
{
// Skip null letters (in case a word can't be formed with available letters)
if (letter != null)
{
path.Add(letter.transform.position + new Vector3(.5f, -0.8f, 0)); // Adjusting position to avoid overlap with letter
}
}
if (path.Count > 0)
{
if (hand != null)
{
hand.SetActive(true);
hand.transform.position = path[0];
hand.transform.DOPath(path.ToArray(), 2f, PathType.CatmullRom)
.SetEase(Ease.InOutSine)
.SetLoops(-1, LoopType.Restart);
}
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 47831d486a4f4d869ae4809e05afb516
timeCreated: 1748532563